123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527 |
- import arraySlice from "../Core/arraySlice.js";
- import Cartesian2 from "../Core/Cartesian2.js";
- import Cartesian3 from "../Core/Cartesian3.js";
- import Color from "../Core/Color.js";
- import defined from "../Core/defined.js";
- import defer from "../Core/defer.js";
- import destroyObject from "../Core/destroyObject.js";
- import DistanceDisplayCondition from "../Core/DistanceDisplayCondition.js";
- import Ellipsoid from "../Core/Ellipsoid.js";
- import NearFarScalar from "../Core/NearFarScalar.js";
- import Rectangle from "../Core/Rectangle.js";
- import TaskProcessor from "../Core/TaskProcessor.js";
- import BillboardCollection from "./BillboardCollection.js";
- import Cesium3DTilePointFeature from "./Cesium3DTilePointFeature.js";
- import HorizontalOrigin from "./HorizontalOrigin.js";
- import LabelCollection from "./LabelCollection.js";
- import LabelStyle from "./LabelStyle.js";
- import PolylineCollection from "./PolylineCollection.js";
- import VerticalOrigin from "./VerticalOrigin.js";
- /**
- * Creates a batch of points or billboards and labels.
- *
- * @alias Vector3DTilePoints
- * @constructor
- *
- * @param {Object} options An object with following properties:
- * @param {Uint16Array} options.positions The positions of the polygons.
- * @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 {Cesium3DTileBatchTable} options.batchTable The batch table for the tile containing the batched polygons.
- * @param {Uint16Array} options.batchIds The batch ids for each polygon.
- *
- * @private
- */
- function Vector3DTilePoints(options) {
- // released after the first update
- this._positions = options.positions;
- this._batchTable = options.batchTable;
- this._batchIds = options.batchIds;
- this._rectangle = options.rectangle;
- this._minHeight = options.minimumHeight;
- this._maxHeight = options.maximumHeight;
- this._billboardCollection = undefined;
- this._labelCollection = undefined;
- this._polylineCollection = undefined;
- this._verticesPromise = undefined;
- this._packedBuffer = undefined;
- this._ready = false;
- this._readyPromise = defer();
- this._resolvedPromise = false;
- }
- Object.defineProperties(Vector3DTilePoints.prototype, {
- /**
- * Gets the number of points.
- *
- * @memberof Vector3DTilePoints.prototype
- *
- * @type {Number}
- * @readonly
- */
- pointsLength: {
- get: function () {
- return this._billboardCollection.length;
- },
- },
- /**
- * Gets the texture atlas memory in bytes.
- *
- * @memberof Vector3DTilePoints.prototype
- *
- * @type {Number}
- * @readonly
- */
- texturesByteLength: {
- get: function () {
- const billboardSize = this._billboardCollection.textureAtlas.texture
- .sizeInBytes;
- const labelSize = this._labelCollection._textureAtlas.texture.sizeInBytes;
- return billboardSize + labelSize;
- },
- },
- /**
- * Gets a promise that resolves when the primitive is ready to render.
- * @memberof Vector3DTilePoints.prototype
- * @type {Promise<void>}
- * @readonly
- */
- readyPromise: {
- get: function () {
- return this._readyPromise.promise;
- },
- },
- });
- function packBuffer(points, ellipsoid) {
- const rectangle = points._rectangle;
- const minimumHeight = points._minHeight;
- const maximumHeight = points._maxHeight;
- const packedLength = 2 + Rectangle.packedLength + Ellipsoid.packedLength;
- const packedBuffer = new Float64Array(packedLength);
- let offset = 0;
- packedBuffer[offset++] = minimumHeight;
- packedBuffer[offset++] = maximumHeight;
- Rectangle.pack(rectangle, packedBuffer, offset);
- offset += Rectangle.packedLength;
- Ellipsoid.pack(ellipsoid, packedBuffer, offset);
- return packedBuffer;
- }
- const createVerticesTaskProcessor = new TaskProcessor(
- "createVectorTilePoints",
- 5
- );
- const scratchPosition = new Cartesian3();
- function createPoints(points, ellipsoid) {
- if (defined(points._billboardCollection)) {
- return;
- }
- let positions;
- if (!defined(points._verticesPromise)) {
- positions = points._positions;
- let packedBuffer = points._packedBuffer;
- if (!defined(packedBuffer)) {
- // Copy because they may be the views on the same buffer.
- positions = points._positions = arraySlice(positions);
- points._batchIds = arraySlice(points._batchIds);
- packedBuffer = points._packedBuffer = packBuffer(points, ellipsoid);
- }
- const transferrableObjects = [positions.buffer, packedBuffer.buffer];
- const parameters = {
- positions: positions.buffer,
- packedBuffer: packedBuffer.buffer,
- };
- const verticesPromise = (points._verticesPromise = createVerticesTaskProcessor.scheduleTask(
- parameters,
- transferrableObjects
- ));
- if (!defined(verticesPromise)) {
- // Postponed
- return;
- }
- verticesPromise.then(function (result) {
- points._positions = new Float64Array(result.positions);
- points._ready = true;
- });
- }
- if (points._ready && !defined(points._billboardCollection)) {
- positions = points._positions;
- const batchTable = points._batchTable;
- const batchIds = points._batchIds;
- const billboardCollection = (points._billboardCollection = new BillboardCollection(
- { batchTable: batchTable }
- ));
- const labelCollection = (points._labelCollection = new LabelCollection({
- batchTable: batchTable,
- }));
- const polylineCollection = (points._polylineCollection = new PolylineCollection());
- polylineCollection._useHighlightColor = true;
- const numberOfPoints = positions.length / 3;
- for (let i = 0; i < numberOfPoints; ++i) {
- const id = batchIds[i];
- const position = Cartesian3.unpack(positions, i * 3, scratchPosition);
- const b = billboardCollection.add();
- b.position = position;
- b._batchIndex = id;
- const l = labelCollection.add();
- l.text = " ";
- l.position = position;
- l._batchIndex = id;
- const p = polylineCollection.add();
- p.positions = [Cartesian3.clone(position), Cartesian3.clone(position)];
- }
- points._positions = undefined;
- points._packedBuffer = undefined;
- }
- }
- /**
- * Creates features for each point and places it at the batch id index of features.
- *
- * @param {Vector3DTileContent} content The vector tile content.
- * @param {Cesium3DTileFeature[]} features An array of features where the point features will be placed.
- */
- Vector3DTilePoints.prototype.createFeatures = function (content, features) {
- const billboardCollection = this._billboardCollection;
- const labelCollection = this._labelCollection;
- const polylineCollection = this._polylineCollection;
- const batchIds = this._batchIds;
- const length = batchIds.length;
- for (let i = 0; i < length; ++i) {
- const batchId = batchIds[i];
- const billboard = billboardCollection.get(i);
- const label = labelCollection.get(i);
- const polyline = polylineCollection.get(i);
- features[batchId] = new Cesium3DTilePointFeature(
- content,
- batchId,
- billboard,
- label,
- polyline
- );
- }
- };
- /**
- * Colors the entire tile when enabled is true. The resulting color will be (batch table color * color).
- *
- * @param {Boolean} enabled Whether to enable debug coloring.
- * @param {Color} color The debug color.
- */
- Vector3DTilePoints.prototype.applyDebugSettings = function (enabled, color) {
- if (enabled) {
- Color.clone(color, this._billboardCollection._highlightColor);
- Color.clone(color, this._labelCollection._highlightColor);
- Color.clone(color, this._polylineCollection._highlightColor);
- } else {
- Color.clone(Color.WHITE, this._billboardCollection._highlightColor);
- Color.clone(Color.WHITE, this._labelCollection._highlightColor);
- Color.clone(Color.WHITE, this._polylineCollection._highlightColor);
- }
- };
- function clearStyle(polygons, features) {
- const batchIds = polygons._batchIds;
- const length = batchIds.length;
- for (let i = 0; i < length; ++i) {
- const batchId = batchIds[i];
- const feature = features[batchId];
- feature.show = true;
- feature.pointSize = Cesium3DTilePointFeature.defaultPointSize;
- feature.color = Cesium3DTilePointFeature.defaultColor;
- feature.pointOutlineColor =
- Cesium3DTilePointFeature.defaultPointOutlineColor;
- feature.pointOutlineWidth =
- Cesium3DTilePointFeature.defaultPointOutlineWidth;
- feature.labelColor = Color.WHITE;
- feature.labelOutlineColor = Color.WHITE;
- feature.labelOutlineWidth = 1.0;
- feature.font = "30px sans-serif";
- feature.labelStyle = LabelStyle.FILL;
- feature.labelText = undefined;
- feature.backgroundColor = new Color(0.165, 0.165, 0.165, 0.8);
- feature.backgroundPadding = new Cartesian2(7, 5);
- feature.backgroundEnabled = false;
- feature.scaleByDistance = undefined;
- feature.translucencyByDistance = undefined;
- feature.distanceDisplayCondition = undefined;
- feature.heightOffset = 0.0;
- feature.anchorLineEnabled = false;
- feature.anchorLineColor = Color.WHITE;
- feature.image = undefined;
- feature.disableDepthTestDistance = 0.0;
- feature.horizontalOrigin = HorizontalOrigin.CENTER;
- feature.verticalOrigin = VerticalOrigin.CENTER;
- feature.labelHorizontalOrigin = HorizontalOrigin.RIGHT;
- feature.labelVerticalOrigin = VerticalOrigin.BASELINE;
- }
- }
- const scratchColor = new Color();
- const scratchColor2 = new Color();
- const scratchColor3 = new Color();
- const scratchColor4 = new Color();
- const scratchColor5 = new Color();
- const scratchColor6 = new Color();
- const scratchScaleByDistance = new NearFarScalar();
- const scratchTranslucencyByDistance = new NearFarScalar();
- const scratchDistanceDisplayCondition = new DistanceDisplayCondition();
- /**
- * Apply a style to the content.
- *
- * @param {Cesium3DTileStyle} style The style.
- * @param {Cesium3DTileFeature[]} features The array of features.
- */
- Vector3DTilePoints.prototype.applyStyle = function (style, features) {
- if (!defined(style)) {
- clearStyle(this, features);
- return;
- }
- const batchIds = this._batchIds;
- const length = batchIds.length;
- for (let i = 0; i < length; ++i) {
- const batchId = batchIds[i];
- const feature = features[batchId];
- if (defined(style.show)) {
- feature.show = style.show.evaluate(feature);
- }
- if (defined(style.pointSize)) {
- feature.pointSize = style.pointSize.evaluate(feature);
- }
- if (defined(style.color)) {
- feature.color = style.color.evaluateColor(feature, scratchColor);
- }
- if (defined(style.pointOutlineColor)) {
- feature.pointOutlineColor = style.pointOutlineColor.evaluateColor(
- feature,
- scratchColor2
- );
- }
- if (defined(style.pointOutlineWidth)) {
- feature.pointOutlineWidth = style.pointOutlineWidth.evaluate(feature);
- }
- if (defined(style.labelColor)) {
- feature.labelColor = style.labelColor.evaluateColor(
- feature,
- scratchColor3
- );
- }
- if (defined(style.labelOutlineColor)) {
- feature.labelOutlineColor = style.labelOutlineColor.evaluateColor(
- feature,
- scratchColor4
- );
- }
- if (defined(style.labelOutlineWidth)) {
- feature.labelOutlineWidth = style.labelOutlineWidth.evaluate(feature);
- }
- if (defined(style.font)) {
- feature.font = style.font.evaluate(feature);
- }
- if (defined(style.labelStyle)) {
- feature.labelStyle = style.labelStyle.evaluate(feature);
- }
- if (defined(style.labelText)) {
- feature.labelText = style.labelText.evaluate(feature);
- } else {
- feature.labelText = undefined;
- }
- if (defined(style.backgroundColor)) {
- feature.backgroundColor = style.backgroundColor.evaluateColor(
- feature,
- scratchColor5
- );
- }
- if (defined(style.backgroundPadding)) {
- feature.backgroundPadding = style.backgroundPadding.evaluate(feature);
- }
- if (defined(style.backgroundEnabled)) {
- feature.backgroundEnabled = style.backgroundEnabled.evaluate(feature);
- }
- if (defined(style.scaleByDistance)) {
- const scaleByDistanceCart4 = style.scaleByDistance.evaluate(feature);
- scratchScaleByDistance.near = scaleByDistanceCart4.x;
- scratchScaleByDistance.nearValue = scaleByDistanceCart4.y;
- scratchScaleByDistance.far = scaleByDistanceCart4.z;
- scratchScaleByDistance.farValue = scaleByDistanceCart4.w;
- feature.scaleByDistance = scratchScaleByDistance;
- } else {
- feature.scaleByDistance = undefined;
- }
- if (defined(style.translucencyByDistance)) {
- const translucencyByDistanceCart4 = style.translucencyByDistance.evaluate(
- feature
- );
- scratchTranslucencyByDistance.near = translucencyByDistanceCart4.x;
- scratchTranslucencyByDistance.nearValue = translucencyByDistanceCart4.y;
- scratchTranslucencyByDistance.far = translucencyByDistanceCart4.z;
- scratchTranslucencyByDistance.farValue = translucencyByDistanceCart4.w;
- feature.translucencyByDistance = scratchTranslucencyByDistance;
- } else {
- feature.translucencyByDistance = undefined;
- }
- if (defined(style.distanceDisplayCondition)) {
- const distanceDisplayConditionCart2 = style.distanceDisplayCondition.evaluate(
- feature
- );
- scratchDistanceDisplayCondition.near = distanceDisplayConditionCart2.x;
- scratchDistanceDisplayCondition.far = distanceDisplayConditionCart2.y;
- feature.distanceDisplayCondition = scratchDistanceDisplayCondition;
- } else {
- feature.distanceDisplayCondition = undefined;
- }
- if (defined(style.heightOffset)) {
- feature.heightOffset = style.heightOffset.evaluate(feature);
- }
- if (defined(style.anchorLineEnabled)) {
- feature.anchorLineEnabled = style.anchorLineEnabled.evaluate(feature);
- }
- if (defined(style.anchorLineColor)) {
- feature.anchorLineColor = style.anchorLineColor.evaluateColor(
- feature,
- scratchColor6
- );
- }
- if (defined(style.image)) {
- feature.image = style.image.evaluate(feature);
- } else {
- feature.image = undefined;
- }
- if (defined(style.disableDepthTestDistance)) {
- feature.disableDepthTestDistance = style.disableDepthTestDistance.evaluate(
- feature
- );
- }
- if (defined(style.horizontalOrigin)) {
- feature.horizontalOrigin = style.horizontalOrigin.evaluate(feature);
- }
- if (defined(style.verticalOrigin)) {
- feature.verticalOrigin = style.verticalOrigin.evaluate(feature);
- }
- if (defined(style.labelHorizontalOrigin)) {
- feature.labelHorizontalOrigin = style.labelHorizontalOrigin.evaluate(
- feature
- );
- }
- if (defined(style.labelVerticalOrigin)) {
- feature.labelVerticalOrigin = style.labelVerticalOrigin.evaluate(feature);
- }
- }
- };
- /**
- * @private
- */
- Vector3DTilePoints.prototype.update = function (frameState) {
- createPoints(this, frameState.mapProjection.ellipsoid);
- if (!this._ready) {
- return;
- }
- this._polylineCollection.update(frameState);
- this._billboardCollection.update(frameState);
- this._labelCollection.update(frameState);
- if (!this._resolvedPromise) {
- this._readyPromise.resolve();
- this._resolvedPromise = true;
- }
- };
- /**
- * Returns true if this object was destroyed; otherwise, false.
- * <p>
- * If this object was destroyed, it should not be used; calling any function other than
- * <code>isDestroyed</code> will result in a {@link DeveloperError} exception.
- * </p>
- *
- * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>.
- */
- Vector3DTilePoints.prototype.isDestroyed = function () {
- return false;
- };
- /**
- * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic
- * release of WebGL resources, instead of relying on the garbage collector to destroy this object.
- * <p>
- * Once an object is destroyed, it should not be used; calling any function other than
- * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore,
- * assign the return value (<code>undefined</code>) to the object as done in the example.
- * </p>
- *
- * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
- */
- Vector3DTilePoints.prototype.destroy = function () {
- this._billboardCollection =
- this._billboardCollection && this._billboardCollection.destroy();
- this._labelCollection =
- this._labelCollection && this._labelCollection.destroy();
- this._polylineCollection =
- this._polylineCollection && this._polylineCollection.destroy();
- return destroyObject(this);
- };
- export default Vector3DTilePoints;
|