Skip to content
Merged
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
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

- Updates use of deprecated options on createImageBitmap. [#12664](https://github.com/CesiumGS/cesium/pull/12664)

#### Additions :tada:

- Added `HeightReference` to `Cesium3DTileset.ConstructorOptions` to allow clamping point features in 3D Tile vector data to terrain or 3D Tiles [#11710](https://github.com/CesiumGS/cesium/pull/11710)

## 1.130 - 2025-06-02

### @cesium/engine
Expand Down
2 changes: 2 additions & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu
- [IKangXu](https://github.com/IKangXu)
- [EMapGIS](https://github.com/EMapGIS)
- [CandyACE](https://github.com/CandyACE)
- [EARTHBRAIN, Ltd.](https://www.earthbrain.com/en/)
- [Gregory Diehl](https://github.com/gdiehleb)

## [Individual CLA](Documentation/Contributors/CLAs/individual-contributor-license-agreement-v1.0.pdf)

Expand Down
41 changes: 41 additions & 0 deletions packages/engine/Source/Scene/Cesium3DTileset.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ import ImageryLayerCollection from "./ImageryLayerCollection.js";
* @property {ClippingPlaneCollection} [clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the tileset.
* @property {ClippingPolygonCollection} [clippingPolygons] The {@link ClippingPolygonCollection} 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 {HeightReference} [heightReference] Sets the {@link HeightReference} for point features in vector tilesets.
* @property {Scene} [scene] The {@link CesiumWidget#scene} that the tileset will be rendered in, required for tilesets that specify a {@link heightReference} value for clamping 3D Tiles vector data content- like points, lines, and labels- to terrain or 3D tiles.
* @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.
Expand Down Expand Up @@ -337,6 +339,8 @@ function Cesium3DTileset(options) {
this._tileDebugLabels = undefined;

this._classificationType = options.classificationType;
this._heightReference = options.heightReference;
this._scene = options.scene;

this._ellipsoid = options.ellipsoid ?? Ellipsoid.WGS84;

Expand Down Expand Up @@ -1808,6 +1812,43 @@ Object.defineProperties(Cesium3DTileset.prototype, {
},
},

/**
* Specifies if the height is relative to terrain, 3D Tiles, or both.
* <p>
* This option is only applied to point features in tilesets containing vector data.
* This option requires the Viewer's scene to be passed in through options.scene.
* </p>
*
* @memberof Cesium3DTileset.prototype
*
* @type {HeightReference | undefined}
* @default undefined
*
* @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.
* @readonly
*/
heightReference: {
get: function () {
return this._heightReference;
},
},

/**
* The {@link CesiumWidget#scene} that the tileset will be rendered in, required for tilesets that specify a {@link heightReference} value for clamping 3D Tiles vector data content- like points, lines, and labels- to terrain or 3D tiles.
*
* @member of Cesium3DTileset.prototype
*
* @type {Scene | undefined}
* @default undefined
* @readonly
*
*/
scene: {
get: function () {
return this._scene;
},
},

/**
* Gets an ellipsoid describing the shape of the globe.
*
Expand Down
5 changes: 3 additions & 2 deletions packages/engine/Source/Scene/Vector3DTileContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ function initialize(content, arrayBuffer, byteOffset) {
modelMatrix: modelMatrix,
});
}

const tileset = content._tileset;
if (numberOfPolylines > 0) {
featureTable.featuresLength = numberOfPolylines;

Expand Down Expand Up @@ -570,7 +570,6 @@ function initialize(content, arrayBuffer, byteOffset) {
);
byteOffset += polylinePositionByteLength;

const tileset = content._tileset;
const examineVectorLinesFunction = tileset.examineVectorLinesFunction;
if (defined(examineVectorLinesFunction)) {
const decodedPositions = decodeVectorPolylinePositions(
Expand Down Expand Up @@ -625,6 +624,8 @@ function initialize(content, arrayBuffer, byteOffset) {
maximumHeight: maxHeight,
rectangle: rectangle,
batchTable: batchTable,
heightReference: tileset.heightReference,
scene: tileset.scene,
});
}
}
Expand Down
10 changes: 10 additions & 0 deletions packages/engine/Source/Scene/Vector3DTilePoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import LabelCollection from "./LabelCollection.js";
import LabelStyle from "./LabelStyle.js";
import PolylineCollection from "./PolylineCollection.js";
import VerticalOrigin from "./VerticalOrigin.js";
import HeightReference from "./HeightReference.js";

/**
* Creates a batch of points or billboards and labels.
Expand All @@ -27,8 +28,10 @@ import VerticalOrigin from "./VerticalOrigin.js";
* @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 {HeightReference} options.heightReference Determines how billboard and label features are positioned relative to terrain or 3d tiles.
* @param {Cesium3DTileBatchTable} options.batchTable The batch table for the tile containing the batched polygons.
* @param {Uint16Array} options.batchIds The batch ids for each polygon.
* @param {Scene} options.scene The Cesium Viewer {@link Scene}. This is required for clamping billboards and labels with {@link HeightReference}
*
* @private
*/
Expand All @@ -42,12 +45,15 @@ function Vector3DTilePoints(options) {
this._rectangle = options.rectangle;
this._minHeight = options.minimumHeight;
this._maxHeight = options.maximumHeight;
this._heightReference = options.heightReference;

this._billboardCollection = new BillboardCollection({
batchTable: options.batchTable,
scene: options.scene,
});
this._labelCollection = new LabelCollection({
batchTable: options.batchTable,
scene: options.scene,
});
this._polylineCollection = new PolylineCollection();
this._polylineCollection._useHighlightColor = true;
Expand Down Expand Up @@ -175,6 +181,8 @@ function createPoints(points, ellipsoid) {
const batchIds = points._batchIds;
const numberOfPoints = positions.length / 3;

const heightReference = points._heightReference ?? HeightReference.NONE;

for (let i = 0; i < numberOfPoints; ++i) {
const id = batchIds[i];

Expand All @@ -183,11 +191,13 @@ function createPoints(points, ellipsoid) {
const b = billboardCollection.add();
b.position = position;
b._batchIndex = id;
b.heightReference = heightReference;

const l = labelCollection.add();
l.text = " ";
l.position = position;
l._batchIndex = id;
l.heightReference = heightReference;

const p = polylineCollection.add();
p.positions = [Cartesian3.clone(position), Cartesian3.clone(position)];
Expand Down
17 changes: 17 additions & 0 deletions packages/engine/Specs/Scene/Vector3DTileContentSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
Cesium3DTileset,
Cesium3DTileStyle,
ClassificationType,
HeightReference,
Color,
ColorGeometryInstanceAttribute,
destroyObject,
Expand Down Expand Up @@ -613,6 +614,22 @@ describe(
expect(scene).toRender(whitePixel);
});
});

it("sets the heightReference for Vector3DTilePoints", async () => {
const heightReference = HeightReference.CLAMP_TO_3D_TILE;
const tileset = await Cesium3DTilesTester.loadTileset(
scene,
vectorTilePointsTileset,
{
heightReference: heightReference,
scene,
},
);
const vectorTile = tileset._root.children[0];
const vectorTilePoint = vectorTile._content._points;

expect(vectorTilePoint._heightReference).toEqual(heightReference);
});
});

describe("polygons", () => {
Expand Down
58 changes: 58 additions & 0 deletions packages/engine/Specs/Scene/Vector3DTilePointsSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
DistanceDisplayCondition,
Ellipsoid,
Math as CesiumMath,
HeightReference,
NearFarScalar,
Rectangle,
Cesium3DTileBatchTable,
Expand Down Expand Up @@ -577,6 +578,7 @@ describe(
maxHeight,
cartoPositions,
);
const heightReference = HeightReference.CLAMP_TO_TERRAIN;

const batchTable = new Cesium3DTileBatchTable(mockTileset, 1);
batchTable.update(mockTileset, scene.frameState);
Expand All @@ -589,6 +591,8 @@ describe(
rectangle: rectangle,
minimumHeight: minHeight,
maximumHeight: maxHeight,
heightReference: heightReference,
scene,
}),
);

Expand Down Expand Up @@ -616,10 +620,64 @@ describe(
}).then(function () {
expect(billboard.ready).toEqual(true);
expect(scene).toRender([0, 0, 255, 255]);
expect(billboard.heightReference).toEqual(heightReference);
});
});
});

it("renders a point with a label", function () {
const minHeight = 0.0;
const maxHeight = 100.0;
const cartoPositions = [Cartographic.fromDegrees(0.0, 0.0, 10.0)];
const positions = encodePositions(
rectangle,
minHeight,
maxHeight,
cartoPositions,
);
const heightReference = HeightReference.CLAMP_TO_TERRAIN;

const batchTable = new Cesium3DTileBatchTable(mockTileset, 1);
batchTable.update(mockTileset, scene.frameState);

points = scene.primitives.add(
new Vector3DTilePoints({
positions: positions,
batchTable: batchTable,
batchIds: new Uint16Array([0]),
rectangle: rectangle,
minimumHeight: minHeight,
maximumHeight: maxHeight,
heightReference: heightReference,
scene,
}),
);

const style = new Cesium3DTileStyle({
labelText: '"test"',
labelColor: "rgba(100, 255, 0, 255)",
labelHorizontalOrigin: HorizontalOrigin.LEFT,
});
return loadPoints(points).then(function () {
const features = [];
points.createFeatures(mockTileset, features);
points.applyStyle(style, features);

const collection = points._labelCollection;
expect(collection.length).toEqual(1);
const label = collection.get(0);
expect(label).toBeDefined();

scene.camera.lookAt(
Cartesian3.fromDegrees(0.0, 0.0, 10.0),
new Cartesian3(0.0, 0.0, 50.0),
);

expect(scene).toRender([100, 255, 0, 255]);
expect(label.heightReference).toEqual(heightReference);
});
});

it("renders multiple points with debug color", function () {
const minHeight = 0.0;
const maxHeight = 100.0;
Expand Down