diff --git a/packages/engine/Source/Core/VectorPipeline.js b/packages/engine/Source/Core/VectorPipeline.js index d3c0083488a..cd1241cac2f 100644 --- a/packages/engine/Source/Core/VectorPipeline.js +++ b/packages/engine/Source/Core/VectorPipeline.js @@ -111,11 +111,11 @@ const scratchSegmentEnd = new Cartesian2(); class VectorPipeline { /** * @param {BufferPolylineCollection} collection - * @param {TilingScheme} tilingScheme + * @param {Ellipsoid} ellipsoid * @param {VectorCollectionData} [result] * @returns {VectorCollectionData} */ - static packPolylineCollectionData(collection, tilingScheme, result) { + static packPolylineCollectionData(collection, ellipsoid, result) { if ( defined(result) && collection._dirtyCount === 0 && @@ -126,7 +126,6 @@ class VectorPipeline { const primitiveCount = collection.primitiveCount; const boundingVolume = collection.boundingVolume; - const ellipsoid = tilingScheme.ellipsoid; const rectangle = Rectangle.fromBoundingSphere(boundingVolume, ellipsoid); const positions = _getProjectedPositions(collection, ellipsoid); @@ -330,11 +329,11 @@ class VectorPipeline { /** * @param {BufferPolygonCollection} collection - * @param {TilingScheme} tilingScheme + * @param {Ellipsoid} ellipsoid * @param {VectorCollectionData} [result] * @returns {VectorCollectionData} */ - static packPolygonCollectionData(collection, tilingScheme, result) { + static packPolygonCollectionData(collection, ellipsoid, result) { if ( defined(result) && collection._dirtyCount === 0 && @@ -345,7 +344,6 @@ class VectorPipeline { const primitiveCount = collection.primitiveCount; const boundingVolume = collection.boundingVolume; - const ellipsoid = tilingScheme.ellipsoid; const rectangle = Rectangle.fromBoundingSphere(boundingVolume, ellipsoid); const positions = _getProjectedPositions(collection, ellipsoid); diff --git a/packages/engine/Source/Core/VectorProvider.js b/packages/engine/Source/Core/VectorProvider.js index 003c65450a6..e3b85ac1bae 100644 --- a/packages/engine/Source/Core/VectorProvider.js +++ b/packages/engine/Source/Core/VectorProvider.js @@ -24,7 +24,7 @@ const scratchIntersectRectangle = new Rectangle(); * * @callback PackCollectionData * @param {*} collection - * @param {TilingScheme} tilingScheme + * @param {Ellipsoid} ellipsoid * @param {VectorCollectionData} [result] * @returns {VectorCollectionData} * @private @@ -370,13 +370,14 @@ class VectorProvider { return cache; } - const data = packCollectionData(collection, this._tilingScheme, cache); + const ellipsoid = this.ellipsoid; + const data = packCollectionData(collection, ellipsoid, cache); // If dirty, the version increments +1 when marked clean below. data.version = collection._version + (dirty ? 1 : 0); data.rectangle = Rectangle.fromBoundingSphere( collection.boundingVolume, - this.ellipsoid, + ellipsoid, data.rectangle, ); this._collectionDataCache.set(collection, data); diff --git a/packages/engine/Source/Scene/ClippingPolygonCollection.js b/packages/engine/Source/Scene/ClippingPolygonCollection.js index a4271e49473..8fbcfd37528 100644 --- a/packages/engine/Source/Scene/ClippingPolygonCollection.js +++ b/packages/engine/Source/Scene/ClippingPolygonCollection.js @@ -25,10 +25,16 @@ import Pass from "../Renderer/Pass.js"; import BufferPolygonCollection from "./BufferPolygonCollection.js"; import BufferPrimitiveCollection from "./BufferPrimitiveCollection.js"; import BufferPolygon from "./BufferPolygon.js"; +import Ellipsoid from "../Core/Ellipsoid.js"; +import VectorPipeline from "../Core/VectorPipeline.js"; + +/** @import VectorCollectionData from "../Core/VectorPipeline.js" */ // Reused flyweight for reading/writing individual BufferPolygons. const bufferPolygonScratch = new BufferPolygon(); +const scratchRectangle = new Rectangle(); + /** * Specifies a set of clipping polygons. Clipping polygons selectively disable rendering in a region * inside or outside the specified list of {@link ClippingPolygon} objects for a single glTF model, 3D Tileset, or the globe. @@ -43,6 +49,7 @@ const bufferPolygonScratch = new BufferPolygon(); * @param {boolean} [options.enabled=true] Determines whether the clipping polygons are active. * @param {boolean} [options.inverse=false] If true, a region will be clipped if it is outside of every polygon in the collection. Otherwise, a region will only be clipped if it is on the inside of any polygon. * @param {number} [options.quality=1.0] A scalar that controls the resolution of the signed distance texture used for clipping. Values greater than 1.0 increase quality, values less than 1.0 decrease it. Must be greater than 0.0. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.default] The ellipsoid to use to project the clipping polygons onto the globe. * * @example * const positions = Cesium.Cartesian3.fromRadiansArray([ @@ -167,6 +174,13 @@ function ClippingPolygonCollection(options) { */ this.polygonRemoved = new Event(); + /** + * The ellipsoid to use to project the clipping polygons onto the globe. + * @type {Ellipsoid} + * @default Ellipsoid.default + */ + this.ellipsoid = options.ellipsoid ?? Ellipsoid.default; + // If this ClippingPolygonCollection has an owner, only its owner should update or destroy it. // This is because in a Cesium3DTileset multiple models may reference the tileset's ClippingPolygonCollection. this._owner = undefined; @@ -180,6 +194,14 @@ function ClippingPolygonCollection(options) { this._signedDistanceTexture = undefined; this._signedDistanceComputeCommand = undefined; + + /** + * @type {VectorCollectionData} + */ + this._vectorCollectionData = VectorPipeline.packPolygonCollectionData( + this._bufferPolygonCollection, + this.ellipsoid, + ); } Object.defineProperties(ClippingPolygonCollection.prototype, { @@ -938,6 +960,12 @@ ClippingPolygonCollection.prototype.update = function (frameState) { } this._signedDistanceComputeCommand = createSignedDistanceTextureCommand(this); + + // Update the vector polygon data + this._vectorCollectionData = VectorPipeline.packPolygonCollectionData( + this._bufferPolygonCollection, + this.ellipsoid, + ); }; function createDebugCommand(texture, context) { @@ -1110,6 +1138,62 @@ ClippingPolygonCollection.setOwner = function ( } }; +/** + * Compute data and pack into textures used for vector-style clipping. + * Consumers must listen to {@link ClippingPolygonCollection#polygonAdded} and {@link ClippingPolygonCollection#polygonRemoved} + * to know when to release stale data and request new data for a given rectangle. + * + * @param {Rectangle} rectangle The region of space to to consider for clipping. Polygons outside of this rectangle + * will not be included in the returned data. + * @param {Context} context The context to use for creating textures. + * @returns {VectorTileData} The data (including textures) for the clipping polygons in the specified rectangle. + * + * @ignore + */ +ClippingPolygonCollection.prototype.requestRectangleData = function ( + rectangle, + context, +) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("rectangle", rectangle); + Check.typeOf.object("context", context); + //>>includeEnd('debug'); + + const vectorTileData = {}; + + // Early out if there are no polygons or the rectangle does not intersect the collection's bounding rectangle + const collectionRectangle = this._vectorCollectionData.rectangle; + if ( + this.length === 0 || + !Rectangle.intersection(rectangle, collectionRectangle, scratchRectangle) + ) { + return vectorTileData; + } + + VectorPipeline.packPolygonRings( + this._bufferPolygonCollection, + this._vectorCollectionData, + rectangle, + vectorTileData, + ); + + VectorPipeline.packPolygonGrid(vectorTileData); + + VectorPipeline.packPolygonTextures(context, vectorTileData); + + return vectorTileData; +}; + +/** + * Destroy resources associated with the given rectangle data. + * + * @param {VectorTileData} rectangleData The data (including textures) for the clipping polygons in the specified rectangle. + * @ignore + */ +ClippingPolygonCollection.prototype.releaseRectangleData = function (data) { + VectorPipeline.freeResources(data); +}; + /** * Function for checking if the context will allow clipping polygons, which require floating point textures. *