| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 | import Color from "../Core/Color.js";import combine from "../Core/combine.js";import defaultValue from "../Core/defaultValue.js";import defined from "../Core/defined.js";import destroyObject from "../Core/destroyObject.js";import DeveloperError from "../Core/DeveloperError.js";import CesiumMath from "../Core/Math.js";import Pass from "../Renderer/Pass.js";import Cesium3DTileBatchTable from "./Cesium3DTileBatchTable.js";import Cesium3DTileFeature from "./Cesium3DTileFeature.js";import Cesium3DTileRefine from "./Cesium3DTileRefine.js";import PointCloud from "./PointCloud.js";import PointCloudShading from "./PointCloudShading.js";import SceneMode from "./SceneMode.js";/** * Represents the contents of a * {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification/TileFormats/PointCloud|Point Cloud} * tile in a {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification|3D Tiles} tileset. * <p> * Implements the {@link Cesium3DTileContent} interface. * </p> * * @alias PointCloud3DTileContent * @constructor * * @private */function PointCloud3DTileContent(  tileset,  tile,  resource,  arrayBuffer,  byteOffset) {  this._tileset = tileset;  this._tile = tile;  this._resource = resource;  this._metadata = undefined;  this._pickId = undefined; // Only defined when batchTable is undefined  this._batchTable = undefined; // Used when feature table contains BATCH_ID semantic  this._styleDirty = false;  this._features = undefined;  this.featurePropertiesDirty = false;  this._group = undefined;  this._pointCloud = new PointCloud({    arrayBuffer: arrayBuffer,    byteOffset: byteOffset,    cull: false,    opaquePass: Pass.CESIUM_3D_TILE,    vertexShaderLoaded: getVertexShaderLoaded(this),    fragmentShaderLoaded: getFragmentShaderLoaded(this),    uniformMapLoaded: getUniformMapLoaded(this),    batchTableLoaded: getBatchTableLoaded(this),    pickIdLoaded: getPickIdLoaded(this),  });}Object.defineProperties(PointCloud3DTileContent.prototype, {  featuresLength: {    get: function () {      if (defined(this._batchTable)) {        return this._batchTable.featuresLength;      }      return 0;    },  },  pointsLength: {    get: function () {      return this._pointCloud.pointsLength;    },  },  trianglesLength: {    get: function () {      return 0;    },  },  geometryByteLength: {    get: function () {      return this._pointCloud.geometryByteLength;    },  },  texturesByteLength: {    get: function () {      return 0;    },  },  batchTableByteLength: {    get: function () {      if (defined(this._batchTable)) {        return this._batchTable.memorySizeInBytes;      }      return 0;    },  },  innerContents: {    get: function () {      return undefined;    },  },  readyPromise: {    get: function () {      return this._pointCloud.readyPromise;    },  },  tileset: {    get: function () {      return this._tileset;    },  },  tile: {    get: function () {      return this._tile;    },  },  url: {    get: function () {      return this._resource.getUrlComponent(true);    },  },  metadata: {    get: function () {      return this._metadata;    },    set: function (value) {      this._metadata = value;    },  },  batchTable: {    get: function () {      return this._batchTable;    },  },  group: {    get: function () {      return this._group;    },    set: function (value) {      this._group = value;    },  },});function getVertexShaderLoaded(content) {  return function (vs) {    if (defined(content._batchTable)) {      return content._batchTable.getVertexShaderCallback(        false,        "a_batchId",        undefined      )(vs);    }    return vs;  };}function getFragmentShaderLoaded(content) {  return function (fs) {    if (defined(content._batchTable)) {      return content._batchTable.getFragmentShaderCallback(        false,        undefined,        false      )(fs);    }    return `uniform vec4 czm_pickColor;\n${fs}`;  };}function getUniformMapLoaded(content) {  return function (uniformMap) {    if (defined(content._batchTable)) {      return content._batchTable.getUniformMapCallback()(uniformMap);    }    return combine(uniformMap, {      czm_pickColor: function () {        return content._pickId.color;      },    });  };}function getBatchTableLoaded(content) {  return function (batchLength, batchTableJson, batchTableBinary) {    content._batchTable = new Cesium3DTileBatchTable(      content,      batchLength,      batchTableJson,      batchTableBinary    );  };}function getPickIdLoaded(content) {  return function () {    return defined(content._batchTable)      ? content._batchTable.getPickId()      : "czm_pickColor";  };}function getGeometricError(content) {  const pointCloudShading = content._tileset.pointCloudShading;  const sphereVolume = content._tile.contentBoundingVolume.boundingSphere.volume();  const baseResolutionApproximation = CesiumMath.cbrt(    sphereVolume / content.pointsLength  );  let geometricError = content._tile.geometricError;  if (geometricError === 0) {    if (      defined(pointCloudShading) &&      defined(pointCloudShading.baseResolution)    ) {      geometricError = pointCloudShading.baseResolution;    } else {      geometricError = baseResolutionApproximation;    }  }  return geometricError;}function createFeatures(content) {  const featuresLength = content.featuresLength;  if (!defined(content._features) && featuresLength > 0) {    const features = new Array(featuresLength);    for (let i = 0; i < featuresLength; ++i) {      features[i] = new Cesium3DTileFeature(content, i);    }    content._features = features;  }}PointCloud3DTileContent.prototype.hasProperty = function (batchId, name) {  if (defined(this._batchTable)) {    return this._batchTable.hasProperty(batchId, name);  }  return false;};/** * Part of the {@link Cesium3DTileContent} interface. * * In this context a feature refers to a group of points that share the same BATCH_ID. * For example all the points that represent a door in a house point cloud would be a feature. * * Features are backed by a batch table and can be colored, shown/hidden, picked, etc like features * in b3dm and i3dm. * * When the BATCH_ID semantic is omitted and the point cloud stores per-point properties, they * are not accessible by getFeature. They are only used for dynamic styling. */PointCloud3DTileContent.prototype.getFeature = function (batchId) {  if (!defined(this._batchTable)) {    return undefined;  }  const featuresLength = this.featuresLength;  //>>includeStart('debug', pragmas.debug);  if (!defined(batchId) || batchId < 0 || batchId >= featuresLength) {    throw new DeveloperError(      `batchId is required and between zero and featuresLength - 1 (${        featuresLength - 1      }).`    );  }  //>>includeEnd('debug');  createFeatures(this);  return this._features[batchId];};PointCloud3DTileContent.prototype.applyDebugSettings = function (  enabled,  color) {  this._pointCloud.color = enabled ? color : Color.WHITE;};PointCloud3DTileContent.prototype.applyStyle = function (style) {  if (defined(this._batchTable)) {    this._batchTable.applyStyle(style);  } else {    this._styleDirty = true;  }};const defaultShading = new PointCloudShading();PointCloud3DTileContent.prototype.update = function (tileset, frameState) {  const pointCloud = this._pointCloud;  const pointCloudShading = defaultValue(    tileset.pointCloudShading,    defaultShading  );  const tile = this._tile;  const batchTable = this._batchTable;  const mode = frameState.mode;  const clippingPlanes = tileset.clippingPlanes;  if (!defined(this._pickId) && !defined(batchTable)) {    this._pickId = frameState.context.createPickId({      primitive: tileset,      content: this,    });  }  if (defined(batchTable)) {    batchTable.update(tileset, frameState);  }  let boundingSphere;  if (defined(tile._contentBoundingVolume)) {    boundingSphere =      mode === SceneMode.SCENE3D        ? tile._contentBoundingVolume.boundingSphere        : tile._contentBoundingVolume2D.boundingSphere;  } else {    boundingSphere =      mode === SceneMode.SCENE3D        ? tile._boundingVolume.boundingSphere        : tile._boundingVolume2D.boundingSphere;  }  const styleDirty = this._styleDirty;  this._styleDirty = false;  pointCloud.clippingPlanesOriginMatrix = tileset.clippingPlanesOriginMatrix;  pointCloud.style = defined(batchTable) ? undefined : tileset.style;  pointCloud.styleDirty = styleDirty;  pointCloud.modelMatrix = tile.computedTransform;  pointCloud.time = tileset.timeSinceLoad;  pointCloud.shadows = tileset.shadows;  pointCloud.boundingSphere = boundingSphere;  pointCloud.clippingPlanes = clippingPlanes;  pointCloud.isClipped =    defined(clippingPlanes) && clippingPlanes.enabled && tile._isClipped;  pointCloud.clippingPlanesDirty = tile.clippingPlanesDirty;  pointCloud.attenuation = pointCloudShading.attenuation;  pointCloud.backFaceCulling = pointCloudShading.backFaceCulling;  pointCloud.normalShading = pointCloudShading.normalShading;  pointCloud.geometricError = getGeometricError(this);  pointCloud.geometricErrorScale = pointCloudShading.geometricErrorScale;  pointCloud.splitDirection = tileset.splitDirection;  if (    defined(pointCloudShading) &&    defined(pointCloudShading.maximumAttenuation)  ) {    pointCloud.maximumAttenuation = pointCloudShading.maximumAttenuation;  } else if (tile.refine === Cesium3DTileRefine.ADD) {    pointCloud.maximumAttenuation = 5.0;  } else {    pointCloud.maximumAttenuation = tileset.maximumScreenSpaceError;  }  pointCloud.update(frameState);};PointCloud3DTileContent.prototype.isDestroyed = function () {  return false;};PointCloud3DTileContent.prototype.destroy = function () {  this._pickId = this._pickId && this._pickId.destroy();  this._pointCloud = this._pointCloud && this._pointCloud.destroy();  this._batchTable = this._batchTable && this._batchTable.destroy();  return destroyObject(this);};export default PointCloud3DTileContent;
 |