@cesium/engine 22.0.0 → 22.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Build/ThirdParty/Workers/zip-web-worker.js +10 -7
- package/Build/Workers/{chunk-AARZSH4V.js → chunk-2JNPWPLE.js} +8 -6
- package/Build/Workers/{chunk-M7HRE4QR.js → chunk-2YVTOY5Z.js} +15 -11
- package/Build/Workers/{chunk-QSMIHPUM.js → chunk-35J4D6PX.js} +3 -3
- package/Build/Workers/{chunk-XQ347YWU.js → chunk-3HUEBDFC.js} +16 -14
- package/Build/Workers/chunk-3JB2X2PR.js +2058 -0
- package/Build/Workers/{chunk-N52ZRKUE.js → chunk-4I7BCCNU.js} +6 -6
- package/Build/Workers/{chunk-NE5JTQJP.js → chunk-4MCPC4TE.js} +10 -8
- package/Build/Workers/{chunk-SZN34LQ5.js → chunk-4ZQN7M7E.js} +10 -10
- package/Build/Workers/{chunk-AOM3FHBN.js → chunk-64PJ4MTB.js} +69 -7
- package/Build/Workers/{chunk-LEFQBK6H.js → chunk-72LZ3FN6.js} +14 -12
- package/Build/Workers/{chunk-3GL53OCU.js → chunk-7CDQUIP5.js} +276 -2277
- package/Build/Workers/{chunk-ECHAJNQJ.js → chunk-7MGTX4WP.js} +12 -12
- package/Build/Workers/{chunk-5B7VZQZY.js → chunk-7OPRTZBT.js} +9 -7
- package/Build/Workers/{chunk-A4DPJIWS.js → chunk-A3NUMZBG.js} +8 -6
- package/Build/Workers/{chunk-FA3SCJDX.js → chunk-AMWXJ5A7.js} +2 -2
- package/Build/Workers/{chunk-NGKF5NTR.js → chunk-BKYJBTHW.js} +13 -5
- package/Build/Workers/{chunk-QCMRUVVF.js → chunk-C35SJ4QP.js} +15 -13
- package/Build/Workers/{chunk-LWJXCI3F.js → chunk-C6FTHSJA.js} +8 -6
- package/Build/Workers/{chunk-2D3GLFZD.js → chunk-CQCEPC6N.js} +15 -13
- package/Build/Workers/{chunk-KGLDJRSO.js → chunk-DCR62BCO.js} +19 -13
- package/Build/Workers/{chunk-KUB64XW6.js → chunk-DIJ7IG5D.js} +12 -10
- package/Build/Workers/{chunk-NHZNMTIR.js → chunk-ED4UXMYY.js} +5 -5
- package/Build/Workers/{chunk-JZFU2LEM.js → chunk-FM5XPC2E.js} +4 -4
- package/Build/Workers/chunk-FPRM6PCE.js +1460 -0
- package/Build/Workers/{chunk-34YXP222.js → chunk-G6WQA27G.js} +5 -5
- package/Build/Workers/{chunk-5ZF53EY6.js → chunk-GMHDOQPH.js} +4 -4
- package/Build/Workers/{chunk-MXHRZHDF.js → chunk-I45CATZK.js} +16 -36
- package/Build/Workers/{chunk-OUBBMEWX.js → chunk-I4D5IP46.js} +9 -7
- package/Build/Workers/{chunk-A6JAFSZT.js → chunk-IVN5HSOI.js} +8 -6
- package/Build/Workers/{chunk-RCCYW6E7.js → chunk-IWOSJVFQ.js} +19 -15
- package/Build/Workers/{chunk-JDJAPBZP.js → chunk-JERDRSEI.js} +1 -1
- package/Build/Workers/{chunk-H7B7FU2U.js → chunk-JFN2DQHY.js} +5 -5
- package/Build/Workers/chunk-JONWM4IO.js +55 -0
- package/Build/Workers/{chunk-EJO3NKMS.js → chunk-JUOSYFXT.js} +1 -1
- package/Build/Workers/{chunk-726NINF5.js → chunk-K64RQCRK.js} +20 -18
- package/Build/Workers/{chunk-L7U26FFD.js → chunk-K6BXEBAF.js} +20 -18
- package/Build/Workers/{chunk-YLXWC7OW.js → chunk-L2FSBEW2.js} +7 -5
- package/Build/Workers/{chunk-OE22564R.js → chunk-LDSQMLRC.js} +3 -3
- package/Build/Workers/{chunk-U7CX3HHE.js → chunk-MSTAVM2N.js} +15 -11
- package/Build/Workers/{chunk-IGX772ZQ.js → chunk-MWGB6DLR.js} +1 -1
- package/Build/Workers/{chunk-5T5SY63I.js → chunk-N5MNKWED.js} +2 -2
- package/Build/Workers/{chunk-XPVZWY4A.js → chunk-NY3CWLIZ.js} +12 -8
- package/Build/Workers/{chunk-XZO6F23E.js → chunk-O3GWUTWM.js} +1 -1
- package/Build/Workers/{chunk-VCVA7BMD.js → chunk-P7ISUYLW.js} +4 -4
- package/Build/Workers/{chunk-U4XMLGSR.js → chunk-PMDPP22G.js} +7 -7
- package/Build/Workers/{chunk-P2H75UV5.js → chunk-PSHZAHFE.js} +16 -11
- package/Build/Workers/{chunk-YLILBDWK.js → chunk-QO6Z5UJE.js} +2 -2
- package/Build/Workers/{chunk-EZ7NJXQN.js → chunk-SDUH3N6G.js} +4 -4
- package/Build/Workers/{chunk-GYRDA3XK.js → chunk-UBJYWGMV.js} +20 -16
- package/Build/Workers/{chunk-7XEJGXX2.js → chunk-V26Y7ZQL.js} +886 -50
- package/Build/Workers/{chunk-6HBKE43B.js → chunk-VGH2CSC7.js} +13 -9
- package/Build/Workers/{chunk-75HAJIDT.js → chunk-VSZ5DB2W.js} +1 -1
- package/Build/Workers/{chunk-W4PIP5PG.js → chunk-WH4HDRGN.js} +2 -2
- package/Build/Workers/{chunk-VVZ667H6.js → chunk-XPNY2VY3.js} +2 -2
- package/Build/Workers/{chunk-7KAXDKRU.js → chunk-YFEZPDAY.js} +13 -11
- package/Build/Workers/{chunk-RQRODXVN.js → chunk-ZGWX2R5I.js} +5 -1424
- package/Build/Workers/{chunk-BJSNGGBM.js → chunk-ZUWF63QU.js} +4 -4
- package/Build/Workers/combineGeometry.js +24 -21
- package/Build/Workers/createBoxGeometry.js +18 -15
- package/Build/Workers/createBoxOutlineGeometry.js +16 -13
- package/Build/Workers/createCircleGeometry.js +28 -24
- package/Build/Workers/createCircleOutlineGeometry.js +21 -17
- package/Build/Workers/createCoplanarPolygonGeometry.js +35 -31
- package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +33 -29
- package/Build/Workers/createCorridorGeometry.js +32 -28
- package/Build/Workers/createCorridorOutlineGeometry.js +30 -26
- package/Build/Workers/createCylinderGeometry.js +20 -17
- package/Build/Workers/createCylinderOutlineGeometry.js +20 -16
- package/Build/Workers/createEllipseGeometry.js +28 -24
- package/Build/Workers/createEllipseOutlineGeometry.js +21 -17
- package/Build/Workers/createEllipsoidGeometry.js +19 -16
- package/Build/Workers/createEllipsoidOutlineGeometry.js +18 -15
- package/Build/Workers/createFrustumGeometry.js +18 -15
- package/Build/Workers/createFrustumOutlineGeometry.js +18 -15
- package/Build/Workers/createGeometry.js +25 -21
- package/Build/Workers/createGroundPolylineGeometry.js +25 -21
- package/Build/Workers/createPlaneGeometry.js +16 -13
- package/Build/Workers/createPlaneOutlineGeometry.js +15 -12
- package/Build/Workers/createPolygonGeometry.js +35 -31
- package/Build/Workers/createPolygonOutlineGeometry.js +32 -28
- package/Build/Workers/createPolylineGeometry.js +27 -23
- package/Build/Workers/createPolylineVolumeGeometry.js +33 -29
- package/Build/Workers/createPolylineVolumeOutlineGeometry.js +29 -25
- package/Build/Workers/createRectangleGeometry.js +30 -26
- package/Build/Workers/createRectangleOutlineGeometry.js +23 -19
- package/Build/Workers/createSimplePolylineGeometry.js +25 -21
- package/Build/Workers/createSphereGeometry.js +19 -16
- package/Build/Workers/createSphereOutlineGeometry.js +18 -15
- package/Build/Workers/createTaskProcessorWorker.js +3 -3
- package/Build/Workers/createVectorTileClampedPolylines.js +16 -13
- package/Build/Workers/createVectorTileGeometries.js +24 -21
- package/Build/Workers/createVectorTilePoints.js +15 -12
- package/Build/Workers/createVectorTilePolygons.js +24 -20
- package/Build/Workers/createVectorTilePolylines.js +16 -13
- package/Build/Workers/createVerticesFromCesium3DTilesTerrain.js +25 -22
- package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +26 -21
- package/Build/Workers/createVerticesFromHeightmap.js +26 -21
- package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +24 -19
- package/Build/Workers/createWallGeometry.js +26 -22
- package/Build/Workers/createWallOutlineGeometry.js +25 -21
- package/Build/Workers/decodeDraco.js +10 -10
- package/Build/Workers/decodeGoogleEarthEnterprisePacket.js +5 -5
- package/Build/Workers/decodeI3S.js +13 -11
- package/Build/Workers/gaussianSplatSorter.js +4 -4
- package/Build/Workers/gaussianSplatTextureGenerator.js +4 -4
- package/Build/Workers/incrementallyBuildTerrainPicker.js +121 -0
- package/Build/Workers/transcodeKTX2.js +6 -6
- package/Build/Workers/transferTypedArrayTest.js +1 -1
- package/Build/Workers/upsampleQuantizedTerrainMesh.js +24 -20
- package/Build/Workers/upsampleVerticesFromCesium3DTilesTerrain.js +25 -22
- package/Source/Core/AxisAlignedBoundingBox.js +36 -0
- package/Source/Core/Cesium3DTilesTerrainData.js +2 -0
- package/Source/Core/Cesium3DTilesTerrainGeometryProcessor.js +2 -0
- package/Source/Core/GoogleEarthEnterpriseTerrainData.js +1 -0
- package/Source/Core/HeightmapTerrainData.js +2 -0
- package/Source/Core/IntersectionTests.js +80 -0
- package/Source/Core/Ion.js +1 -1
- package/Source/Core/QuantizedMeshTerrainData.js +1 -0
- package/Source/Core/TerrainMesh.js +207 -0
- package/Source/Core/TerrainPicker.js +607 -0
- package/Source/Core/TexturePacker.js +27 -12
- package/Source/Core/Transforms.js +28 -19
- package/Source/DataSources/BillboardGraphics.js +1 -1
- package/Source/DataSources/BillboardVisualizer.js +7 -4
- package/Source/Renderer/Buffer.js +32 -0
- package/Source/Renderer/BufferUsage.js +3 -1
- package/Source/Renderer/Context.js +85 -7
- package/Source/Renderer/Sync.js +104 -0
- package/Source/Renderer/TextureAtlas.js +75 -44
- package/Source/Scene/ArcGisMapService.js +1 -1
- package/Source/Scene/Azure2DImageryProvider.js +103 -20
- package/Source/Scene/Billboard.js +75 -28
- package/Source/Scene/BillboardCollection.js +21 -2
- package/Source/Scene/BillboardTexture.js +56 -7
- package/Source/Scene/Globe.js +3 -1
- package/Source/Scene/GlobeSurfaceTile.js +18 -66
- package/Source/Scene/GlobeSurfaceTileProvider.js +11 -0
- package/Source/Scene/Google2DImageryProvider.js +10 -15
- package/Source/Scene/LabelCollection.js +1 -0
- package/Source/Scene/PickFramebuffer.js +124 -36
- package/Source/Scene/Picking.js +99 -17
- package/Source/Scene/Scene.js +36 -4
- package/Source/Scene/TerrainFillMesh.js +1 -0
- package/Source/Shaders/BillboardCollectionFS.glsl +22 -9
- package/Source/Shaders/BillboardCollectionFS.js +22 -9
- package/Source/ThirdParty/Workers/zip-web-worker.js +1 -1
- package/Source/ThirdParty/zip-module.wasm +0 -0
- package/Source/Workers/incrementallyBuildTerrainPicker.js +108 -0
- package/index.d.ts +204 -4
- package/index.js +65 -63
- package/package.json +4 -4
|
@@ -101,6 +101,8 @@ function Google2DImageryProvider(options) {
|
|
|
101
101
|
key: encodeURIComponent(options.key),
|
|
102
102
|
});
|
|
103
103
|
|
|
104
|
+
this._resource = resource.clone();
|
|
105
|
+
|
|
104
106
|
let credit;
|
|
105
107
|
if (defined(options.credit)) {
|
|
106
108
|
credit = options.credit;
|
|
@@ -312,7 +314,7 @@ Object.defineProperties(Google2DImageryProvider.prototype, {
|
|
|
312
314
|
* });
|
|
313
315
|
* @example
|
|
314
316
|
* // Google 2D roadmap overlay with custom styles
|
|
315
|
-
* const
|
|
317
|
+
* const googleTilesProvider = Cesium.Google2DImageryProvider.fromIonAssetId({
|
|
316
318
|
* assetId: 3830184,
|
|
317
319
|
* overlayLayerType: "layerRoadmap",
|
|
318
320
|
* styles: [
|
|
@@ -403,7 +405,7 @@ Google2DImageryProvider.fromIonAssetId = async function (options) {
|
|
|
403
405
|
* // Google 2D roadmap overlay with custom styles
|
|
404
406
|
* Cesium.GoogleMaps.defaultApiKey = "your-api-key";
|
|
405
407
|
*
|
|
406
|
-
* const
|
|
408
|
+
* const googleTilesProvider = Cesium.Google2DImageryProvider.fromUrl({
|
|
407
409
|
* overlayLayerType: "layerRoadmap",
|
|
408
410
|
* styles: [
|
|
409
411
|
* {
|
|
@@ -492,7 +494,7 @@ Google2DImageryProvider.prototype.requestImage = function (
|
|
|
492
494
|
}
|
|
493
495
|
|
|
494
496
|
// Asynchronously request and populate _attributionsByLevel if it hasn't been already. We do this here so that the promise can be properly awaited.
|
|
495
|
-
if (
|
|
497
|
+
if (!defined(this._attributionsByLevel)) {
|
|
496
498
|
return Promise.all([promise, this.getViewportCredits()]).then(
|
|
497
499
|
(results) => results[0],
|
|
498
500
|
);
|
|
@@ -533,12 +535,7 @@ Google2DImageryProvider.prototype.getViewportCredits = async function () {
|
|
|
533
535
|
const promises = [];
|
|
534
536
|
for (let level = 0; level < maximumLevel + 1; level++) {
|
|
535
537
|
promises.push(
|
|
536
|
-
fetchViewportAttribution(
|
|
537
|
-
this._viewportUrl,
|
|
538
|
-
this._key,
|
|
539
|
-
this._session,
|
|
540
|
-
level,
|
|
541
|
-
),
|
|
538
|
+
fetchViewportAttribution(this._resource, this._viewportUrl, level),
|
|
542
539
|
);
|
|
543
540
|
}
|
|
544
541
|
const results = await Promise.all(promises);
|
|
@@ -559,12 +556,10 @@ Google2DImageryProvider.prototype.getViewportCredits = async function () {
|
|
|
559
556
|
return attributionsByLevel;
|
|
560
557
|
};
|
|
561
558
|
|
|
562
|
-
async function fetchViewportAttribution(
|
|
563
|
-
const
|
|
564
|
-
url
|
|
559
|
+
async function fetchViewportAttribution(resource, url, level) {
|
|
560
|
+
const viewportResource = resource.getDerivedResource({
|
|
561
|
+
url,
|
|
565
562
|
queryParameters: {
|
|
566
|
-
key,
|
|
567
|
-
session,
|
|
568
563
|
zoom: level,
|
|
569
564
|
north: 90,
|
|
570
565
|
south: -90,
|
|
@@ -573,7 +568,7 @@ async function fetchViewportAttribution(url, key, session, level) {
|
|
|
573
568
|
},
|
|
574
569
|
data: JSON.stringify(Frozen.EMPTY_OBJECT),
|
|
575
570
|
});
|
|
576
|
-
const viewportJson =
|
|
571
|
+
const viewportJson = await viewportResource.fetchJson();
|
|
577
572
|
return viewportJson.copyright;
|
|
578
573
|
}
|
|
579
574
|
|
|
@@ -118,6 +118,7 @@ function unbindGlyphBillboard(labelCollection, glyph) {
|
|
|
118
118
|
const billboard = glyph.billboard;
|
|
119
119
|
if (defined(billboard)) {
|
|
120
120
|
billboard.show = false;
|
|
121
|
+
billboard._clampedPosition = undefined;
|
|
121
122
|
if (defined(billboard._removeCallbackFunc)) {
|
|
122
123
|
billboard._removeCallbackFunc();
|
|
123
124
|
billboard._removeCallbackFunc = undefined;
|
|
@@ -4,6 +4,10 @@ import defined from "../Core/defined.js";
|
|
|
4
4
|
import destroyObject from "../Core/destroyObject.js";
|
|
5
5
|
import FramebufferManager from "../Renderer/FramebufferManager.js";
|
|
6
6
|
import PassState from "../Renderer/PassState.js";
|
|
7
|
+
import PixelDatatype from "../Renderer/PixelDatatype.js";
|
|
8
|
+
import PixelFormat from "../Core/PixelFormat.js";
|
|
9
|
+
import Sync from "../Renderer/Sync.js";
|
|
10
|
+
import RuntimeError from "../Core/RuntimeError.js";
|
|
7
11
|
|
|
8
12
|
/**
|
|
9
13
|
* @private
|
|
@@ -27,47 +31,18 @@ function PickFramebuffer(context) {
|
|
|
27
31
|
this._height = 0;
|
|
28
32
|
}
|
|
29
33
|
|
|
30
|
-
PickFramebuffer.prototype.begin = function (screenSpaceRectangle, viewport) {
|
|
31
|
-
const context = this._context;
|
|
32
|
-
const { width, height } = viewport;
|
|
33
|
-
|
|
34
|
-
BoundingRectangle.clone(
|
|
35
|
-
screenSpaceRectangle,
|
|
36
|
-
this._passState.scissorTest.rectangle,
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
// Create or recreate renderbuffers and framebuffer used for picking
|
|
40
|
-
this._width = width;
|
|
41
|
-
this._height = height;
|
|
42
|
-
this._fb.update(context, width, height);
|
|
43
|
-
this._passState.framebuffer = this._fb.framebuffer;
|
|
44
|
-
|
|
45
|
-
this._passState.viewport.width = width;
|
|
46
|
-
this._passState.viewport.height = height;
|
|
47
|
-
|
|
48
|
-
return this._passState;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
34
|
/**
|
|
52
|
-
* Return the picked
|
|
35
|
+
* Return the picked object(s) rendered within a given rectangle.
|
|
53
36
|
*
|
|
54
|
-
* @
|
|
37
|
+
* @private
|
|
38
|
+
* @param {object} context The active context.
|
|
39
|
+
* @param {Uint8Array|Uint16Array|Float32Array|Uint32Array} pixels The pixels in the specified rectangle.
|
|
40
|
+
* @param {number} width The rectangle width.
|
|
41
|
+
* @param {number} height The rectangle height.
|
|
55
42
|
* @param {number} [limit=1] If supplied, stop iterating after collecting this many objects.
|
|
56
43
|
* @returns {object[]} A list of rendered objects, ordered by distance to the middle of the rectangle.
|
|
57
44
|
*/
|
|
58
|
-
|
|
59
|
-
const width = screenSpaceRectangle.width ?? 1.0;
|
|
60
|
-
const height = screenSpaceRectangle.height ?? 1.0;
|
|
61
|
-
|
|
62
|
-
const context = this._context;
|
|
63
|
-
const pixels = context.readPixels({
|
|
64
|
-
x: screenSpaceRectangle.x,
|
|
65
|
-
y: screenSpaceRectangle.y,
|
|
66
|
-
width: width,
|
|
67
|
-
height: height,
|
|
68
|
-
framebuffer: this._fb.framebuffer,
|
|
69
|
-
});
|
|
70
|
-
|
|
45
|
+
function pickObjectsFromPixels(context, pixels, width, height, limit = 1) {
|
|
71
46
|
const max = Math.max(width, height);
|
|
72
47
|
const length = max * max;
|
|
73
48
|
const halfWidth = Math.floor(width * 0.5);
|
|
@@ -121,6 +96,119 @@ PickFramebuffer.prototype.end = function (screenSpaceRectangle, limit = 1) {
|
|
|
121
96
|
y += dy;
|
|
122
97
|
}
|
|
123
98
|
return [...objects];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
PickFramebuffer.prototype.begin = function (screenSpaceRectangle, viewport) {
|
|
102
|
+
const context = this._context;
|
|
103
|
+
const { width, height } = viewport;
|
|
104
|
+
|
|
105
|
+
BoundingRectangle.clone(
|
|
106
|
+
screenSpaceRectangle,
|
|
107
|
+
this._passState.scissorTest.rectangle,
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// Create or recreate renderbuffers and framebuffer used for picking
|
|
111
|
+
this._width = width;
|
|
112
|
+
this._height = height;
|
|
113
|
+
this._fb.update(context, width, height);
|
|
114
|
+
this._passState.framebuffer = this._fb.framebuffer;
|
|
115
|
+
|
|
116
|
+
this._passState.viewport.width = width;
|
|
117
|
+
this._passState.viewport.height = height;
|
|
118
|
+
|
|
119
|
+
return this._passState;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Return the picked objects rendered within a given rectangle using asynchronously without stalling the GPU.
|
|
124
|
+
* Requires WebGL2.
|
|
125
|
+
*
|
|
126
|
+
* @param {BoundingRectangle} screenSpaceRectangle
|
|
127
|
+
* @param {FrameState} frameState
|
|
128
|
+
* @param {number} [limit=1] If supplied, stop iterating after collecting this many objects.
|
|
129
|
+
* @returns {Promise<object[]>} A list of rendered objects, ordered by distance to the middle of the rectangle.
|
|
130
|
+
*
|
|
131
|
+
* @exception {RuntimeError} Async Picking Request Timeout.
|
|
132
|
+
* @exception {DeveloperError} A WebGL 2 context is required.
|
|
133
|
+
*/
|
|
134
|
+
PickFramebuffer.prototype.endAsync = async function (
|
|
135
|
+
screenSpaceRectangle,
|
|
136
|
+
frameState,
|
|
137
|
+
limit = 1,
|
|
138
|
+
) {
|
|
139
|
+
const width = screenSpaceRectangle.width ?? 1.0;
|
|
140
|
+
const height = screenSpaceRectangle.height ?? 1.0;
|
|
141
|
+
|
|
142
|
+
const context = this._context;
|
|
143
|
+
const framebuffer = this._fb.framebuffer;
|
|
144
|
+
|
|
145
|
+
let pixelDatatype = PixelDatatype.UNSIGNED_BYTE;
|
|
146
|
+
let pixelFormat = PixelFormat.RGBA;
|
|
147
|
+
|
|
148
|
+
if (defined(framebuffer) && framebuffer.numberOfColorAttachments > 0) {
|
|
149
|
+
pixelDatatype = framebuffer.getColorTexture(0).pixelDatatype;
|
|
150
|
+
pixelFormat = framebuffer.getColorTexture(0).pixelFormat;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const pbo = context.readPixelsToPBO({
|
|
154
|
+
x: screenSpaceRectangle.x,
|
|
155
|
+
y: screenSpaceRectangle.y,
|
|
156
|
+
width: width,
|
|
157
|
+
height: height,
|
|
158
|
+
framebuffer: framebuffer,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
const sync = Sync.create({
|
|
162
|
+
context: context,
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Wait for the GPU to signal that it is ready to readback the PBO data
|
|
166
|
+
try {
|
|
167
|
+
await sync.waitForSignal((next) => frameState.afterRender.push(next));
|
|
168
|
+
const pixels = PixelFormat.createTypedArray(
|
|
169
|
+
pixelFormat,
|
|
170
|
+
pixelDatatype,
|
|
171
|
+
width,
|
|
172
|
+
height,
|
|
173
|
+
);
|
|
174
|
+
pbo.getBufferData(pixels);
|
|
175
|
+
const pickedObjects = pickObjectsFromPixels(
|
|
176
|
+
context,
|
|
177
|
+
pixels,
|
|
178
|
+
width,
|
|
179
|
+
height,
|
|
180
|
+
limit,
|
|
181
|
+
);
|
|
182
|
+
return pickedObjects;
|
|
183
|
+
} catch (e) {
|
|
184
|
+
throw new RuntimeError("Async Picking Request Timeout");
|
|
185
|
+
} finally {
|
|
186
|
+
sync.destroy();
|
|
187
|
+
pbo.destroy();
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Return the picked objects rendered within a given rectangle.
|
|
193
|
+
*
|
|
194
|
+
* @param {BoundingRectangle} screenSpaceRectangle
|
|
195
|
+
* @param {number} [limit=1] If supplied, stop iterating after collecting this many objects.
|
|
196
|
+
* @returns {object[]} A list of rendered objects, ordered by distance to the middle of the rectangle.
|
|
197
|
+
*/
|
|
198
|
+
PickFramebuffer.prototype.end = function (screenSpaceRectangle, limit = 1) {
|
|
199
|
+
const width = screenSpaceRectangle.width ?? 1.0;
|
|
200
|
+
const height = screenSpaceRectangle.height ?? 1.0;
|
|
201
|
+
|
|
202
|
+
const context = this._context;
|
|
203
|
+
const pixels = context.readPixels({
|
|
204
|
+
x: screenSpaceRectangle.x,
|
|
205
|
+
y: screenSpaceRectangle.y,
|
|
206
|
+
width: width,
|
|
207
|
+
height: height,
|
|
208
|
+
framebuffer: this._fb.framebuffer,
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
return pickObjectsFromPixels(context, pixels, width, height, limit);
|
|
124
212
|
};
|
|
125
213
|
|
|
126
214
|
/**
|
package/Source/Scene/Picking.js
CHANGED
|
@@ -8,6 +8,7 @@ import Color from "../Core/Color.js";
|
|
|
8
8
|
import defined from "../Core/defined.js";
|
|
9
9
|
import DeveloperError from "../Core/DeveloperError.js";
|
|
10
10
|
import Matrix4 from "../Core/Matrix4.js";
|
|
11
|
+
import oneTimeWarning from "../Core/oneTimeWarning.js";
|
|
11
12
|
import OrthographicFrustum from "../Core/OrthographicFrustum.js";
|
|
12
13
|
import OrthographicOffCenterFrustum from "../Core/OrthographicOffCenterFrustum.js";
|
|
13
14
|
import PerspectiveFrustum from "../Core/PerspectiveFrustum.js";
|
|
@@ -262,30 +263,21 @@ function computePickingDrawingBufferRectangle(
|
|
|
262
263
|
}
|
|
263
264
|
|
|
264
265
|
/**
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
* type of primitive and may be used to further identify the picked object.
|
|
268
|
-
* <p>
|
|
269
|
-
* When a feature of a 3D Tiles tileset is picked, <code>pick</code> returns a {@link Cesium3DTileFeature} object.
|
|
270
|
-
* </p>
|
|
266
|
+
* Setup needed before picking.
|
|
267
|
+
*
|
|
271
268
|
* @param {Scene} scene
|
|
272
269
|
* @param {Cartesian2} windowPosition Window coordinates to perform picking on.
|
|
270
|
+
* @param {BoundingRectangle} drawingBufferRectangle The output drawing buffer recangle.
|
|
273
271
|
* @param {number} [width=3] Width of the pick rectangle.
|
|
274
272
|
* @param {number} [height=3] Height of the pick rectangle.
|
|
275
|
-
* @param {number} [limit=1] If supplied, stop iterating after collecting this many objects.
|
|
276
|
-
* @returns {object[]} List of objects containing the picked primitives.
|
|
277
273
|
*/
|
|
278
|
-
|
|
274
|
+
function pickBegin(
|
|
279
275
|
scene,
|
|
280
276
|
windowPosition,
|
|
277
|
+
drawingBufferRectangle,
|
|
281
278
|
width,
|
|
282
279
|
height,
|
|
283
|
-
limit = 1,
|
|
284
280
|
) {
|
|
285
|
-
//>>includeStart('debug', pragmas.debug);
|
|
286
|
-
Check.defined("windowPosition", windowPosition);
|
|
287
|
-
//>>includeEnd('debug');
|
|
288
|
-
|
|
289
281
|
const { context, frameState, defaultView } = scene;
|
|
290
282
|
const { viewport, pickFramebuffer } = defaultView;
|
|
291
283
|
|
|
@@ -304,12 +296,12 @@ Picking.prototype.pick = function (
|
|
|
304
296
|
windowPosition,
|
|
305
297
|
scratchPosition,
|
|
306
298
|
);
|
|
307
|
-
|
|
299
|
+
computePickingDrawingBufferRectangle(
|
|
308
300
|
context.drawingBufferHeight,
|
|
309
301
|
drawingBufferPosition,
|
|
310
302
|
width,
|
|
311
303
|
height,
|
|
312
|
-
|
|
304
|
+
drawingBufferRectangle,
|
|
313
305
|
);
|
|
314
306
|
|
|
315
307
|
scene.jobScheduler.disableThisFrame();
|
|
@@ -334,9 +326,99 @@ Picking.prototype.pick = function (
|
|
|
334
326
|
|
|
335
327
|
scene.updateAndExecuteCommands(passState, scratchColorZero);
|
|
336
328
|
scene.resolveFramebuffers(passState);
|
|
329
|
+
}
|
|
337
330
|
|
|
338
|
-
|
|
331
|
+
/**
|
|
332
|
+
* Teardown needed after picking.
|
|
333
|
+
*
|
|
334
|
+
* @param {Scene} scene
|
|
335
|
+
*/
|
|
336
|
+
function pickEnd(scene) {
|
|
337
|
+
const { context } = scene;
|
|
339
338
|
context.endFrame();
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Same operation as {@link Picking#pick}, but returns a Promise that resolves asynchronously without blocking the main render thread.
|
|
343
|
+
* Requires WebGL2 else using synchronous fallback.
|
|
344
|
+
*
|
|
345
|
+
* @see Picking#pick
|
|
346
|
+
*
|
|
347
|
+
* @param {Scene} scene
|
|
348
|
+
* @param {Cartesian2} windowPosition Window coordinates to perform picking on.
|
|
349
|
+
* @param {number} [width=3] Width of the pick rectangle.
|
|
350
|
+
* @param {number} [height=3] Height of the pick rectangle.
|
|
351
|
+
* @param {number} [limit=1] If supplied, stop iterating after collecting this many objects.
|
|
352
|
+
* @returns {Promise<object[]>} List of objects containing the picked primitives.
|
|
353
|
+
*
|
|
354
|
+
* @exception {RuntimeError} Async Picking Request Timeout.
|
|
355
|
+
*/
|
|
356
|
+
Picking.prototype.pickAsync = async function (
|
|
357
|
+
scene,
|
|
358
|
+
windowPosition,
|
|
359
|
+
width,
|
|
360
|
+
height,
|
|
361
|
+
limit = 1,
|
|
362
|
+
) {
|
|
363
|
+
//>>includeStart('debug', pragmas.debug);
|
|
364
|
+
Check.defined("windowPosition", windowPosition);
|
|
365
|
+
//>>includeEnd('debug');
|
|
366
|
+
|
|
367
|
+
const { context, frameState, defaultView } = scene;
|
|
368
|
+
const { pickFramebuffer } = defaultView;
|
|
369
|
+
const drawingBufferRectangle = scratchRectangle;
|
|
370
|
+
pickBegin(scene, windowPosition, drawingBufferRectangle, width, height);
|
|
371
|
+
let pickedObjects;
|
|
372
|
+
if (context.webgl2) {
|
|
373
|
+
pickedObjects = pickFramebuffer.endAsync(
|
|
374
|
+
drawingBufferRectangle,
|
|
375
|
+
frameState,
|
|
376
|
+
limit,
|
|
377
|
+
); // Promise<Object[]>
|
|
378
|
+
} else {
|
|
379
|
+
pickedObjects = pickFramebuffer.end(drawingBufferRectangle, limit); // Object[]
|
|
380
|
+
pickedObjects = Promise.resolve(pickedObjects); // Promise<Object[]> Wrap as Promise
|
|
381
|
+
oneTimeWarning(
|
|
382
|
+
"picking-async-fallback",
|
|
383
|
+
"Fallback to synchronous picking because async operation requires WebGL2 context.",
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
pickEnd(scene);
|
|
387
|
+
return pickedObjects;
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Returns a list of objects with a <code>primitive</code> property that contains the first (top) primitives
|
|
392
|
+
* in the scene at a particular window coordinate. Other properties may potentially be set depending on the
|
|
393
|
+
* type of primitive and may be used to further identify the picked object.
|
|
394
|
+
* <p>
|
|
395
|
+
* When a feature of a 3D Tiles tileset is picked, <code>pick</code> returns a {@link Cesium3DTileFeature} object.
|
|
396
|
+
* </p>
|
|
397
|
+
* @param {Scene} scene
|
|
398
|
+
* @param {Cartesian2} windowPosition Window coordinates to perform picking on.
|
|
399
|
+
* @param {number} [width=3] Width of the pick rectangle.
|
|
400
|
+
* @param {number} [height=3] Height of the pick rectangle.
|
|
401
|
+
* @param {number} [limit=1] If supplied, stop iterating after collecting this many objects.
|
|
402
|
+
* @returns {object[]} List of objects containing the picked primitives.
|
|
403
|
+
*
|
|
404
|
+
*/
|
|
405
|
+
Picking.prototype.pick = function (
|
|
406
|
+
scene,
|
|
407
|
+
windowPosition,
|
|
408
|
+
width,
|
|
409
|
+
height,
|
|
410
|
+
limit = 1,
|
|
411
|
+
) {
|
|
412
|
+
//>>includeStart('debug', pragmas.debug);
|
|
413
|
+
Check.defined("windowPosition", windowPosition);
|
|
414
|
+
//>>includeEnd('debug');
|
|
415
|
+
|
|
416
|
+
const { defaultView } = scene;
|
|
417
|
+
const { pickFramebuffer } = defaultView;
|
|
418
|
+
const drawingBufferRectangle = scratchRectangle;
|
|
419
|
+
pickBegin(scene, windowPosition, drawingBufferRectangle, width, height);
|
|
420
|
+
const pickedObjects = pickFramebuffer.end(drawingBufferRectangle, limit); // Object[]
|
|
421
|
+
pickEnd(scene);
|
|
340
422
|
return pickedObjects;
|
|
341
423
|
};
|
|
342
424
|
|
package/Source/Scene/Scene.js
CHANGED
|
@@ -3932,14 +3932,15 @@ function callAfterRenderFunctions(scene) {
|
|
|
3932
3932
|
// Functions are queued up during primitive update and executed here in case
|
|
3933
3933
|
// the function modifies scene state that should remain constant over the frame.
|
|
3934
3934
|
const functions = scene._frameState.afterRender;
|
|
3935
|
-
|
|
3936
|
-
|
|
3935
|
+
const functionsCpy = functions.slice(); // Snapshot before iterate allows callbacks to add functions for next frame
|
|
3936
|
+
functions.length = 0;
|
|
3937
|
+
|
|
3938
|
+
for (let i = 0; i < functionsCpy.length; ++i) {
|
|
3939
|
+
const shouldRequestRender = functionsCpy[i]();
|
|
3937
3940
|
if (shouldRequestRender) {
|
|
3938
3941
|
scene.requestRender();
|
|
3939
3942
|
}
|
|
3940
3943
|
}
|
|
3941
|
-
|
|
3942
|
-
functions.length = 0;
|
|
3943
3944
|
}
|
|
3944
3945
|
|
|
3945
3946
|
function getGlobeHeight(scene) {
|
|
@@ -4517,6 +4518,37 @@ Scene.prototype.pick = function (windowPosition, width, height) {
|
|
|
4517
4518
|
return this._picking.pick(this, windowPosition, width, height, 1)[0];
|
|
4518
4519
|
};
|
|
4519
4520
|
|
|
4521
|
+
/**
|
|
4522
|
+
* Performs the same operation as Scene.pick but asynchonosly without blocking the main render thread.
|
|
4523
|
+
* Requires WebGL2 else using fallback.
|
|
4524
|
+
*
|
|
4525
|
+
* @example
|
|
4526
|
+
* // On mouse over, color the feature yellow.
|
|
4527
|
+
* handler.setInputAction(function(movement) {
|
|
4528
|
+
* const feature = scene.pickAsync(movement.endPosition).then(function(feature) {
|
|
4529
|
+
* if (feature instanceof Cesium.Cesium3DTileFeature) {
|
|
4530
|
+
* feature.color = Cesium.Color.YELLOW;
|
|
4531
|
+
* }
|
|
4532
|
+
* });
|
|
4533
|
+
* }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
|
|
4534
|
+
*
|
|
4535
|
+
* @param {Cartesian2} windowPosition Window coordinates to perform picking on.
|
|
4536
|
+
* @param {number} [width=3] Width of the pick rectangle.
|
|
4537
|
+
* @param {number} [height=3] Height of the pick rectangle.
|
|
4538
|
+
* @returns {Promise<Object | undefined>} Object containing the picked primitive or <code>undefined</code> if nothing is at the location.
|
|
4539
|
+
*
|
|
4540
|
+
* @see Scene#pick
|
|
4541
|
+
*/
|
|
4542
|
+
Scene.prototype.pickAsync = async function (windowPosition, width, height) {
|
|
4543
|
+
const result = await this._picking.pickAsync(
|
|
4544
|
+
this,
|
|
4545
|
+
windowPosition,
|
|
4546
|
+
width,
|
|
4547
|
+
height,
|
|
4548
|
+
1,
|
|
4549
|
+
);
|
|
4550
|
+
return result[0];
|
|
4551
|
+
};
|
|
4520
4552
|
/**
|
|
4521
4553
|
* Returns a {@link VoxelCell} for the voxel sample rendered at a particular window coordinate,
|
|
4522
4554
|
* or <code>undefined</code> if no voxel is rendered at that position.
|
|
@@ -1274,6 +1274,7 @@ function createFillMesh(tileProvider, frameState, tile, vertexArraysToDestroy) {
|
|
|
1274
1274
|
vertexCount,
|
|
1275
1275
|
minimumHeight,
|
|
1276
1276
|
maximumHeight,
|
|
1277
|
+
rectangle,
|
|
1277
1278
|
BoundingSphere.fromOrientedBoundingBox(obb),
|
|
1278
1279
|
computeOccludeePoint(
|
|
1279
1280
|
tileProvider,
|
|
@@ -131,7 +131,9 @@ void doThreePointDepthTest(float eyeDepth, bool applyTranslate) {
|
|
|
131
131
|
}
|
|
132
132
|
#endif
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
// Extra manual depth testing is done to allow more control over how a billboard is occluded
|
|
135
|
+
// by the globe when near and far from the camera.
|
|
136
|
+
void doDepthTest(float globeDepth) {
|
|
135
137
|
float temp = v_compressed.y;
|
|
136
138
|
temp = temp * SHIFT_RIGHT1;
|
|
137
139
|
float temp2 = (temp - floor(temp)) * SHIFT_LEFT1;
|
|
@@ -156,14 +158,10 @@ void doDepthTest() {
|
|
|
156
158
|
}
|
|
157
159
|
#endif
|
|
158
160
|
|
|
159
|
-
// Automatic depth testing of billboards is disabled (@see BillboardCollection#update).
|
|
160
|
-
// Instead, we do one of two types of manual depth tests (potentially in addition to the test above), depending on the camera's distance to the billboard fragment.
|
|
161
161
|
// If we're far away, we just compare against a flat, camera-facing depth-plane at the ellipsoid's center.
|
|
162
162
|
// If we're close, we compare against the globe depth texture (which includes depth from the 3D tile pass).
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (globeDepth == 0.0) return; // Not on globe
|
|
166
|
-
|
|
163
|
+
|
|
164
|
+
if (globeDepth == 0.0) return; // Not on globe
|
|
167
165
|
float distanceToEllipsoidCenter = -length(czm_viewerPositionWC); // depth is negative by convention
|
|
168
166
|
float testDistance = (eyeDepth > -u_coarseDepthTestDistance) ? globeDepth : distanceToEllipsoidCenter;
|
|
169
167
|
if (eyeDepth < testDistance) {
|
|
@@ -175,7 +173,10 @@ void main()
|
|
|
175
173
|
{
|
|
176
174
|
if (v_splitDirection < 0.0 && gl_FragCoord.x > czm_splitPosition) discard;
|
|
177
175
|
if (v_splitDirection > 0.0 && gl_FragCoord.x < czm_splitPosition) discard;
|
|
178
|
-
|
|
176
|
+
|
|
177
|
+
vec2 fragSt = gl_FragCoord.xy / czm_viewport.zw;
|
|
178
|
+
float globeDepth = getGlobeDepthAtCoords(fragSt);
|
|
179
|
+
doDepthTest(globeDepth);
|
|
179
180
|
|
|
180
181
|
vec4 color = texture(u_atlas, v_textureCoordinates);
|
|
181
182
|
|
|
@@ -243,6 +244,18 @@ void main()
|
|
|
243
244
|
out_FragColor = color;
|
|
244
245
|
|
|
245
246
|
#ifdef LOG_DEPTH
|
|
246
|
-
|
|
247
|
+
// If we've made it here, we passed our manual depth test, above. But the automatic depth test will
|
|
248
|
+
// still run, and some fragments of the billboard may clip against the globe. To prevent that,
|
|
249
|
+
// ensure the depth value we write out is in front of the globe depth.
|
|
250
|
+
float depthArg = v_depthFromNearPlusOne;
|
|
251
|
+
|
|
252
|
+
if (globeDepth != 0.0) { // On the globe
|
|
253
|
+
float globeDepthFromNearPlusOne = (-globeDepth - czm_currentFrustum.x) + 1.0;
|
|
254
|
+
float nudge = max(globeDepthFromNearPlusOne * 5e-6, czm_epsilon7);
|
|
255
|
+
float globeOnTop = max(1.0, globeDepthFromNearPlusOne - nudge);
|
|
256
|
+
depthArg = min(depthArg, globeOnTop);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
czm_writeLogDepth(depthArg);
|
|
247
260
|
#endif
|
|
248
261
|
}
|
|
@@ -132,7 +132,9 @@ void doThreePointDepthTest(float eyeDepth, bool applyTranslate) {\n\
|
|
|
132
132
|
}\n\
|
|
133
133
|
#endif\n\
|
|
134
134
|
\n\
|
|
135
|
-
|
|
135
|
+
// Extra manual depth testing is done to allow more control over how a billboard is occluded \n\
|
|
136
|
+
// by the globe when near and far from the camera.\n\
|
|
137
|
+
void doDepthTest(float globeDepth) {\n\
|
|
136
138
|
float temp = v_compressed.y;\n\
|
|
137
139
|
temp = temp * SHIFT_RIGHT1;\n\
|
|
138
140
|
float temp2 = (temp - floor(temp)) * SHIFT_LEFT1;\n\
|
|
@@ -157,14 +159,10 @@ void doDepthTest() {\n\
|
|
|
157
159
|
}\n\
|
|
158
160
|
#endif\n\
|
|
159
161
|
\n\
|
|
160
|
-
// Automatic depth testing of billboards is disabled (@see BillboardCollection#update).\n\
|
|
161
|
-
// Instead, we do one of two types of manual depth tests (potentially in addition to the test above), depending on the camera's distance to the billboard fragment.\n\
|
|
162
162
|
// If we're far away, we just compare against a flat, camera-facing depth-plane at the ellipsoid's center.\n\
|
|
163
163
|
// If we're close, we compare against the globe depth texture (which includes depth from the 3D tile pass).\n\
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if (globeDepth == 0.0) return; // Not on globe\n\
|
|
167
|
-
\n\
|
|
164
|
+
\n\
|
|
165
|
+
if (globeDepth == 0.0) return; // Not on globe \n\
|
|
168
166
|
float distanceToEllipsoidCenter = -length(czm_viewerPositionWC); // depth is negative by convention\n\
|
|
169
167
|
float testDistance = (eyeDepth > -u_coarseDepthTestDistance) ? globeDepth : distanceToEllipsoidCenter;\n\
|
|
170
168
|
if (eyeDepth < testDistance) {\n\
|
|
@@ -176,7 +174,10 @@ void main()\n\
|
|
|
176
174
|
{\n\
|
|
177
175
|
if (v_splitDirection < 0.0 && gl_FragCoord.x > czm_splitPosition) discard;\n\
|
|
178
176
|
if (v_splitDirection > 0.0 && gl_FragCoord.x < czm_splitPosition) discard;\n\
|
|
179
|
-
|
|
177
|
+
\n\
|
|
178
|
+
vec2 fragSt = gl_FragCoord.xy / czm_viewport.zw;\n\
|
|
179
|
+
float globeDepth = getGlobeDepthAtCoords(fragSt);\n\
|
|
180
|
+
doDepthTest(globeDepth);\n\
|
|
180
181
|
\n\
|
|
181
182
|
vec4 color = texture(u_atlas, v_textureCoordinates);\n\
|
|
182
183
|
\n\
|
|
@@ -244,6 +245,18 @@ void main()\n\
|
|
|
244
245
|
out_FragColor = color;\n\
|
|
245
246
|
\n\
|
|
246
247
|
#ifdef LOG_DEPTH\n\
|
|
247
|
-
|
|
248
|
+
// If we've made it here, we passed our manual depth test, above. But the automatic depth test will\n\
|
|
249
|
+
// still run, and some fragments of the billboard may clip against the globe. To prevent that,\n\
|
|
250
|
+
// ensure the depth value we write out is in front of the globe depth.\n\
|
|
251
|
+
float depthArg = v_depthFromNearPlusOne;\n\
|
|
252
|
+
\n\
|
|
253
|
+
if (globeDepth != 0.0) { // On the globe\n\
|
|
254
|
+
float globeDepthFromNearPlusOne = (-globeDepth - czm_currentFrustum.x) + 1.0;\n\
|
|
255
|
+
float nudge = max(globeDepthFromNearPlusOne * 5e-6, czm_epsilon7);\n\
|
|
256
|
+
float globeOnTop = max(1.0, globeDepthFromNearPlusOne - nudge);\n\
|
|
257
|
+
depthArg = min(depthArg, globeOnTop);\n\
|
|
258
|
+
}\n\
|
|
259
|
+
\n\
|
|
260
|
+
czm_writeLogDepth(depthArg);\n\
|
|
248
261
|
#endif\n\
|
|
249
262
|
}";
|