| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529 | import Cartesian3 from "../Core/Cartesian3.js";import defaultValue from "../Core/defaultValue.js";import defer from "../Core/defer.js";import defined from "../Core/defined.js";import destroyObject from "../Core/destroyObject.js";import DeveloperError from "../Core/DeveloperError.js";import getJsonFromTypedArray from "../Core/getJsonFromTypedArray.js";import Matrix4 from "../Core/Matrix4.js";import RuntimeError from "../Core/RuntimeError.js";import Cesium3DTileBatchTable from "./Cesium3DTileBatchTable.js";import Vector3DTileGeometry from "./Vector3DTileGeometry.js";/** * <p> * Implements the {@link Cesium3DTileContent} interface. * </p> * * @alias Geometry3DTileContent * @constructor * * @private */function Geometry3DTileContent(  tileset,  tile,  resource,  arrayBuffer,  byteOffset) {  this._tileset = tileset;  this._tile = tile;  this._resource = resource;  this._geometries = undefined;  this._contentReadyPromise = undefined;  this._readyPromise = defer();  this._metadata = undefined;  this._batchTable = undefined;  this._features = undefined;  /**   * Part of the {@link Cesium3DTileContent} interface.   */  this.featurePropertiesDirty = false;  this._group = undefined;  initialize(this, arrayBuffer, byteOffset);}Object.defineProperties(Geometry3DTileContent.prototype, {  featuresLength: {    get: function () {      return defined(this._batchTable) ? this._batchTable.featuresLength : 0;    },  },  pointsLength: {    get: function () {      return 0;    },  },  trianglesLength: {    get: function () {      if (defined(this._geometries)) {        return this._geometries.trianglesLength;      }      return 0;    },  },  geometryByteLength: {    get: function () {      if (defined(this._geometries)) {        return this._geometries.geometryByteLength;      }      return 0;    },  },  texturesByteLength: {    get: function () {      return 0;    },  },  batchTableByteLength: {    get: function () {      return defined(this._batchTable) ? this._batchTable.memorySizeInBytes : 0;    },  },  innerContents: {    get: function () {      return undefined;    },  },  readyPromise: {    get: function () {      return this._readyPromise.promise;    },  },  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 createColorChangedCallback(content) {  return function (batchId, color) {    if (defined(content._geometries)) {      content._geometries.updateCommands(batchId, color);    }  };}function getBatchIds(featureTableJson, featureTableBinary) {  let boxBatchIds;  let cylinderBatchIds;  let ellipsoidBatchIds;  let sphereBatchIds;  let i;  const numberOfBoxes = defaultValue(featureTableJson.BOXES_LENGTH, 0);  const numberOfCylinders = defaultValue(featureTableJson.CYLINDERS_LENGTH, 0);  const numberOfEllipsoids = defaultValue(    featureTableJson.ELLIPSOIDS_LENGTH,    0  );  const numberOfSpheres = defaultValue(featureTableJson.SPHERES_LENGTH, 0);  if (numberOfBoxes > 0 && defined(featureTableJson.BOX_BATCH_IDS)) {    const boxBatchIdsByteOffset =      featureTableBinary.byteOffset + featureTableJson.BOX_BATCH_IDS.byteOffset;    boxBatchIds = new Uint16Array(      featureTableBinary.buffer,      boxBatchIdsByteOffset,      numberOfBoxes    );  }  if (numberOfCylinders > 0 && defined(featureTableJson.CYLINDER_BATCH_IDS)) {    const cylinderBatchIdsByteOffset =      featureTableBinary.byteOffset +      featureTableJson.CYLINDER_BATCH_IDS.byteOffset;    cylinderBatchIds = new Uint16Array(      featureTableBinary.buffer,      cylinderBatchIdsByteOffset,      numberOfCylinders    );  }  if (numberOfEllipsoids > 0 && defined(featureTableJson.ELLIPSOID_BATCH_IDS)) {    const ellipsoidBatchIdsByteOffset =      featureTableBinary.byteOffset +      featureTableJson.ELLIPSOID_BATCH_IDS.byteOffset;    ellipsoidBatchIds = new Uint16Array(      featureTableBinary.buffer,      ellipsoidBatchIdsByteOffset,      numberOfEllipsoids    );  }  if (numberOfSpheres > 0 && defined(featureTableJson.SPHERE_BATCH_IDS)) {    const sphereBatchIdsByteOffset =      featureTableBinary.byteOffset +      featureTableJson.SPHERE_BATCH_IDS.byteOffset;    sphereBatchIds = new Uint16Array(      featureTableBinary.buffer,      sphereBatchIdsByteOffset,      numberOfSpheres    );  }  const atLeastOneDefined =    defined(boxBatchIds) ||    defined(cylinderBatchIds) ||    defined(ellipsoidBatchIds) ||    defined(sphereBatchIds);  const atLeastOneUndefined =    (numberOfBoxes > 0 && !defined(boxBatchIds)) ||    (numberOfCylinders > 0 && !defined(cylinderBatchIds)) ||    (numberOfEllipsoids > 0 && !defined(ellipsoidBatchIds)) ||    (numberOfSpheres > 0 && !defined(sphereBatchIds));  if (atLeastOneDefined && atLeastOneUndefined) {    throw new RuntimeError(      "If one group of batch ids is defined, then all batch ids must be defined."    );  }  const allUndefinedBatchIds =    !defined(boxBatchIds) &&    !defined(cylinderBatchIds) &&    !defined(ellipsoidBatchIds) &&    !defined(sphereBatchIds);  if (allUndefinedBatchIds) {    let id = 0;    if (!defined(boxBatchIds) && numberOfBoxes > 0) {      boxBatchIds = new Uint16Array(numberOfBoxes);      for (i = 0; i < numberOfBoxes; ++i) {        boxBatchIds[i] = id++;      }    }    if (!defined(cylinderBatchIds) && numberOfCylinders > 0) {      cylinderBatchIds = new Uint16Array(numberOfCylinders);      for (i = 0; i < numberOfCylinders; ++i) {        cylinderBatchIds[i] = id++;      }    }    if (!defined(ellipsoidBatchIds) && numberOfEllipsoids > 0) {      ellipsoidBatchIds = new Uint16Array(numberOfEllipsoids);      for (i = 0; i < numberOfEllipsoids; ++i) {        ellipsoidBatchIds[i] = id++;      }    }    if (!defined(sphereBatchIds) && numberOfSpheres > 0) {      sphereBatchIds = new Uint16Array(numberOfSpheres);      for (i = 0; i < numberOfSpheres; ++i) {        sphereBatchIds[i] = id++;      }    }  }  return {    boxes: boxBatchIds,    cylinders: cylinderBatchIds,    ellipsoids: ellipsoidBatchIds,    spheres: sphereBatchIds,  };}const sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT;function initialize(content, arrayBuffer, byteOffset) {  byteOffset = defaultValue(byteOffset, 0);  const uint8Array = new Uint8Array(arrayBuffer);  const view = new DataView(arrayBuffer);  byteOffset += sizeOfUint32; // Skip magic number  const version = view.getUint32(byteOffset, true);  if (version !== 1) {    throw new RuntimeError(      `Only Geometry tile version 1 is supported.  Version ${version} is not.`    );  }  byteOffset += sizeOfUint32;  const byteLength = view.getUint32(byteOffset, true);  byteOffset += sizeOfUint32;  if (byteLength === 0) {    content._readyPromise.resolve(content);    return;  }  const featureTableJSONByteLength = view.getUint32(byteOffset, true);  byteOffset += sizeOfUint32;  if (featureTableJSONByteLength === 0) {    throw new RuntimeError(      "Feature table must have a byte length greater than zero"    );  }  const featureTableBinaryByteLength = view.getUint32(byteOffset, true);  byteOffset += sizeOfUint32;  const batchTableJSONByteLength = view.getUint32(byteOffset, true);  byteOffset += sizeOfUint32;  const batchTableBinaryByteLength = view.getUint32(byteOffset, true);  byteOffset += sizeOfUint32;  const featureTableJson = getJsonFromTypedArray(    uint8Array,    byteOffset,    featureTableJSONByteLength  );  byteOffset += featureTableJSONByteLength;  const featureTableBinary = new Uint8Array(    arrayBuffer,    byteOffset,    featureTableBinaryByteLength  );  byteOffset += featureTableBinaryByteLength;  let batchTableJson;  let batchTableBinary;  if (batchTableJSONByteLength > 0) {    // PERFORMANCE_IDEA: is it possible to allocate this on-demand?  Perhaps keep the    // arraybuffer/string compressed in memory and then decompress it when it is first accessed.    //    // We could also make another request for it, but that would make the property set/get    // API async, and would double the number of numbers in some cases.    batchTableJson = getJsonFromTypedArray(      uint8Array,      byteOffset,      batchTableJSONByteLength    );    byteOffset += batchTableJSONByteLength;    if (batchTableBinaryByteLength > 0) {      // Has a batch table binary      batchTableBinary = new Uint8Array(        arrayBuffer,        byteOffset,        batchTableBinaryByteLength      );      // Copy the batchTableBinary section and let the underlying ArrayBuffer be freed      batchTableBinary = new Uint8Array(batchTableBinary);    }  }  const numberOfBoxes = defaultValue(featureTableJson.BOXES_LENGTH, 0);  const numberOfCylinders = defaultValue(featureTableJson.CYLINDERS_LENGTH, 0);  const numberOfEllipsoids = defaultValue(    featureTableJson.ELLIPSOIDS_LENGTH,    0  );  const numberOfSpheres = defaultValue(featureTableJson.SPHERES_LENGTH, 0);  const totalPrimitives =    numberOfBoxes + numberOfCylinders + numberOfEllipsoids + numberOfSpheres;  const batchTable = new Cesium3DTileBatchTable(    content,    totalPrimitives,    batchTableJson,    batchTableBinary,    createColorChangedCallback(content)  );  content._batchTable = batchTable;  if (totalPrimitives === 0) {    return;  }  const modelMatrix = content.tile.computedTransform;  let center;  if (defined(featureTableJson.RTC_CENTER)) {    center = Cartesian3.unpack(featureTableJson.RTC_CENTER);    Matrix4.multiplyByPoint(modelMatrix, center, center);  }  const batchIds = getBatchIds(featureTableJson, featureTableBinary);  if (    numberOfBoxes > 0 ||    numberOfCylinders > 0 ||    numberOfEllipsoids > 0 ||    numberOfSpheres > 0  ) {    let boxes;    let cylinders;    let ellipsoids;    let spheres;    if (numberOfBoxes > 0) {      const boxesByteOffset =        featureTableBinary.byteOffset + featureTableJson.BOXES.byteOffset;      boxes = new Float32Array(        featureTableBinary.buffer,        boxesByteOffset,        Vector3DTileGeometry.packedBoxLength * numberOfBoxes      );    }    if (numberOfCylinders > 0) {      const cylindersByteOffset =        featureTableBinary.byteOffset + featureTableJson.CYLINDERS.byteOffset;      cylinders = new Float32Array(        featureTableBinary.buffer,        cylindersByteOffset,        Vector3DTileGeometry.packedCylinderLength * numberOfCylinders      );    }    if (numberOfEllipsoids > 0) {      const ellipsoidsByteOffset =        featureTableBinary.byteOffset + featureTableJson.ELLIPSOIDS.byteOffset;      ellipsoids = new Float32Array(        featureTableBinary.buffer,        ellipsoidsByteOffset,        Vector3DTileGeometry.packedEllipsoidLength * numberOfEllipsoids      );    }    if (numberOfSpheres > 0) {      const spheresByteOffset =        featureTableBinary.byteOffset + featureTableJson.SPHERES.byteOffset;      spheres = new Float32Array(        featureTableBinary.buffer,        spheresByteOffset,        Vector3DTileGeometry.packedSphereLength * numberOfSpheres      );    }    content._geometries = new Vector3DTileGeometry({      boxes: boxes,      boxBatchIds: batchIds.boxes,      cylinders: cylinders,      cylinderBatchIds: batchIds.cylinders,      ellipsoids: ellipsoids,      ellipsoidBatchIds: batchIds.ellipsoids,      spheres: spheres,      sphereBatchIds: batchIds.spheres,      center: center,      modelMatrix: modelMatrix,      batchTable: batchTable,      boundingVolume: content.tile.boundingVolume.boundingVolume,    });  }}function createFeatures(content) {  const featuresLength = content.featuresLength;  if (!defined(content._features) && featuresLength > 0) {    const features = new Array(featuresLength);    if (defined(content._geometries)) {      content._geometries.createFeatures(content, features);    }    content._features = features;  }}Geometry3DTileContent.prototype.hasProperty = function (batchId, name) {  return this._batchTable.hasProperty(batchId, name);};Geometry3DTileContent.prototype.getFeature = function (batchId) {  //>>includeStart('debug', pragmas.debug);  const featuresLength = this.featuresLength;  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];};Geometry3DTileContent.prototype.applyDebugSettings = function (enabled, color) {  if (defined(this._geometries)) {    this._geometries.applyDebugSettings(enabled, color);  }};Geometry3DTileContent.prototype.applyStyle = function (style) {  createFeatures(this);  if (defined(this._geometries)) {    this._geometries.applyStyle(style, this._features);  }};Geometry3DTileContent.prototype.update = function (tileset, frameState) {  if (defined(this._geometries)) {    this._geometries.classificationType = this._tileset.classificationType;    this._geometries.debugWireframe = this._tileset.debugWireframe;    this._geometries.update(frameState);  }  if (defined(this._batchTable) && this._geometries._ready) {    this._batchTable.update(tileset, frameState);  }  if (!defined(this._contentReadyPromise)) {    const that = this;    this._contentReadyPromise = this._geometries.readyPromise.then(function () {      that._readyPromise.resolve(that);    });  }};Geometry3DTileContent.prototype.isDestroyed = function () {  return false;};Geometry3DTileContent.prototype.destroy = function () {  this._geometries = this._geometries && this._geometries.destroy();  this._batchTable = this._batchTable && this._batchTable.destroy();  return destroyObject(this);};export default Geometry3DTileContent;
 |