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
14 changes: 13 additions & 1 deletion packages/engine/Source/Scene/GlobeSurfaceTile.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ import TerrainState from "./TerrainState.js";
/** @import TerrainProvider from "../Core/TerrainProvider.js"; */
/** @import TileBoundingRegion from "./TileBoundingRegion.js"; */
/** @import TileImagery from "./TileImagery.js"; */
/** @import VectorProvider, { VectorTileData } from "../Core/VectorProvider.js"; */
/** @import VectorProvider from "../Core/VectorProvider.js"; */
/** @import { VectorTileData } from "../Core/VectorPipeline.js"; */

/**
* Contains additional information about a {@link QuadtreeTile} of the globe's surface, and
Expand Down Expand Up @@ -67,6 +68,12 @@ class GlobeSurfaceTile {
/** @type {VectorTileData} */
this.vectorData = undefined;

/**
* Clipping polygons build on top of the vector tile data system (both rely on the same rendering technique).
* @type {VectorTileData}
*/
this.clippingPolygonData = undefined;

/** @type {VertexArray} */
this.vertexArray = undefined;

Expand Down Expand Up @@ -169,6 +176,11 @@ class GlobeSurfaceTile {
this.vectorData = undefined;
}

if (defined(this.clippingPolygonData)) {
VectorPipeline.freeResources(this.clippingPolygonData);
this.clippingPolygonData = undefined;
}

this.terrainData = undefined;

this.terrainState = TerrainState.UNLOADED;
Expand Down
76 changes: 76 additions & 0 deletions packages/engine/Source/Scene/GlobeSurfaceTileProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,12 @@ class GlobeSurfaceTileProvider {
*/
this._clippingPolygons = undefined;

this._clippingPolygonsDirty = false;

this._removeClippingPolygonAdded = undefined;

this._removeClippingPolygonRemoved = undefined;

/**
* A property specifying a {@link Rectangle} used to selectively limit terrain and imagery rendering.
* @type {Rectangle}
Expand Down Expand Up @@ -348,7 +354,33 @@ class GlobeSurfaceTileProvider {
}

set clippingPolygons(value) {
if (value === this._clippingPolygons) {
return;
}

ClippingPolygonCollection.setOwner(value, this, "_clippingPolygons");

// First, remove the previous listeners if they exist
this._removeClippingPolygonAdded =
this._removeClippingPolygonAdded && this._removeClippingPolygonAdded();
this._removeClippingPolygonRemoved =
this._removeClippingPolygonRemoved &&
this._removeClippingPolygonRemoved();

this._clippingPolygonsDirty = true;

if (!defined(value)) {
return;
}

const markDirty = () => {
this._clippingPolygonsDirty = true;
};

this._removeClippingPolygonAdded =
value.polygonAdded.addEventListener(markDirty);
this._removeClippingPolygonRemoved =
value.polygonRemoved.addEventListener(markDirty);
}

/**
Expand Down Expand Up @@ -381,6 +413,21 @@ class GlobeSurfaceTileProvider {
);
}

const clippingPolygons = this._clippingPolygons;
if (defined(clippingPolygons) && this._clippingPolygonsDirty) {
this._quadtree.forEachLoadedTile((tile) => {
const surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
if (defined(surfaceTile?.clippingPolygonData)) {
ClippingPolygonCollection.releaseRectangleData(
surfaceTile.clippingPolygonData,
);
surfaceTile.clippingPolygonData = undefined;
}
});

this._clippingPolygonsDirty = false;
}

// Record regions dirtied by changed collections, re-bake overlapping
// tiles, and build vector data for new surface tiles.
const vectorProvider = this._vectorProvider;
Expand Down Expand Up @@ -410,6 +457,30 @@ class GlobeSurfaceTileProvider {
);
vectorProvider.makeClean();

// Similarly, for clipping polygons, re-request data as needed
if (defined(clippingPolygons)) {
this._quadtree.forEachRenderedTile(
/** @param {QuadtreeTile} tile */
(tile) => {
if (!tile.isClipped) {
return;
}

const surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
// The surface tile's clipping polygon data is cleared above whenever the clipping polygon collection changes.
if (defined(surfaceTile.clippingPolygonData)) {
return;
}

surfaceTile.clippingPolygonData =
clippingPolygons.requestRectangleData(
tile.rectangle,
frameState.context,
);
},
);
}

// Add credits for terrain and imagery providers.
updateCredits(this, frameState);

Expand Down Expand Up @@ -1171,6 +1242,11 @@ class GlobeSurfaceTileProvider {
this._removeLayerMovedListener && this._removeLayerMovedListener();
this._removeLayerShownListener =
this._removeLayerShownListener && this._removeLayerShownListener();
this._removeClippingPolygonAdded =
this._removeClippingPolygonAdded && this._removeClippingPolygonAdded();
this._removeClippingPolygonRemoved =
this._removeClippingPolygonRemoved &&
this._removeClippingPolygonRemoved();

return destroyObject(this);
}
Expand Down
Loading