Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions packages/engine/Source/Core/VectorPipeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand All @@ -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);
Expand Down Expand Up @@ -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 &&
Expand All @@ -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);
Expand Down
7 changes: 4 additions & 3 deletions packages/engine/Source/Core/VectorProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const scratchIntersectRectangle = new Rectangle();
*
* @callback PackCollectionData
* @param {*} collection
* @param {TilingScheme} tilingScheme
* @param {Ellipsoid} ellipsoid
* @param {VectorCollectionData} [result]
* @returns {VectorCollectionData}
* @private
Expand Down Expand Up @@ -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);
Expand Down
84 changes: 84 additions & 0 deletions packages/engine/Source/Scene/ClippingPolygonCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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([
Expand Down Expand Up @@ -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;
Expand All @@ -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, {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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.
*
Expand Down
Loading