123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409 |
- import Cartesian3 from '../Core/Cartesian3.js';
- import defaultValue from '../Core/defaultValue.js';
- import defined from '../Core/defined.js';
- import defineProperties from '../Core/defineProperties.js';
- import destroyObject from '../Core/destroyObject.js';
- import DeveloperError from '../Core/DeveloperError.js';
- import getStringFromTypedArray from '../Core/getStringFromTypedArray.js';
- import Matrix4 from '../Core/Matrix4.js';
- import RuntimeError from '../Core/RuntimeError.js';
- import when from '../ThirdParty/when.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 = when.defer();
- this._batchTable = undefined;
- this._features = undefined;
- /**
- * Part of the {@link Cesium3DTileContent} interface.
- */
- this.featurePropertiesDirty = false;
- initialize(this, arrayBuffer, byteOffset);
- }
- 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);
- }
- },
- batchTable : {
- get : function() {
- return this._batchTable;
- }
- }
- });
- function createColorChangedCallback(content) {
- return function(batchId, color) {
- if (defined(content._geometries)) {
- content._geometries.updateCommands(batchId, color);
- }
- };
- }
- function getBatchIds(featureTableJson, featureTableBinary) {
- var boxBatchIds;
- var cylinderBatchIds;
- var ellipsoidBatchIds;
- var sphereBatchIds;
- var i;
- var numberOfBoxes = defaultValue(featureTableJson.BOXES_LENGTH, 0);
- var numberOfCylinders = defaultValue(featureTableJson.CYLINDERS_LENGTH, 0);
- var numberOfEllipsoids = defaultValue(featureTableJson.ELLIPSOIDS_LENGTH, 0);
- var numberOfSpheres = defaultValue(featureTableJson.SPHERES_LENGTH, 0);
- if (numberOfBoxes > 0 && defined(featureTableJson.BOX_BATCH_IDS)) {
- var boxBatchIdsByteOffset = featureTableBinary.byteOffset + featureTableJson.BOX_BATCH_IDS.byteOffset;
- boxBatchIds = new Uint16Array(featureTableBinary.buffer, boxBatchIdsByteOffset, numberOfBoxes);
- }
- if (numberOfCylinders > 0 && defined(featureTableJson.CYLINDER_BATCH_IDS)) {
- var cylinderBatchIdsByteOffset = featureTableBinary.byteOffset + featureTableJson.CYLINDER_BATCH_IDS.byteOffset;
- cylinderBatchIds = new Uint16Array(featureTableBinary.buffer, cylinderBatchIdsByteOffset, numberOfCylinders);
- }
- if (numberOfEllipsoids > 0 && defined(featureTableJson.ELLIPSOID_BATCH_IDS)) {
- var ellipsoidBatchIdsByteOffset = featureTableBinary.byteOffset + featureTableJson.ELLIPSOID_BATCH_IDS.byteOffset;
- ellipsoidBatchIds = new Uint16Array(featureTableBinary.buffer, ellipsoidBatchIdsByteOffset, numberOfEllipsoids);
- }
- if (numberOfSpheres > 0 && defined(featureTableJson.SPHERE_BATCH_IDS)) {
- var sphereBatchIdsByteOffset = featureTableBinary.byteOffset + featureTableJson.SPHERE_BATCH_IDS.byteOffset;
- sphereBatchIds = new Uint16Array(featureTableBinary.buffer, sphereBatchIdsByteOffset, numberOfSpheres);
- }
- var atLeastOneDefined = defined(boxBatchIds) || defined(cylinderBatchIds) || defined(ellipsoidBatchIds) || defined(sphereBatchIds);
- var 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.');
- }
- var allUndefinedBatchIds = !defined(boxBatchIds) && !defined(cylinderBatchIds) && !defined(ellipsoidBatchIds) && !defined(sphereBatchIds);
- if (allUndefinedBatchIds) {
- var 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
- };
- }
- var sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT;
- function initialize(content, arrayBuffer, byteOffset) {
- byteOffset = defaultValue(byteOffset, 0);
- var uint8Array = new Uint8Array(arrayBuffer);
- var view = new DataView(arrayBuffer);
- byteOffset += sizeOfUint32; // Skip magic number
- var version = view.getUint32(byteOffset, true);
- if (version !== 1) {
- throw new RuntimeError('Only Geometry tile version 1 is supported. Version ' + version + ' is not.');
- }
- byteOffset += sizeOfUint32;
- var byteLength = view.getUint32(byteOffset, true);
- byteOffset += sizeOfUint32;
- if (byteLength === 0) {
- content._readyPromise.resolve(content);
- return;
- }
- var featureTableJSONByteLength = view.getUint32(byteOffset, true);
- byteOffset += sizeOfUint32;
- if (featureTableJSONByteLength === 0) {
- throw new RuntimeError('Feature table must have a byte length greater than zero');
- }
- var featureTableBinaryByteLength = view.getUint32(byteOffset, true);
- byteOffset += sizeOfUint32;
- var batchTableJSONByteLength = view.getUint32(byteOffset, true);
- byteOffset += sizeOfUint32;
- var batchTableBinaryByteLength = view.getUint32(byteOffset, true);
- byteOffset += sizeOfUint32;
- var featureTableString = getStringFromTypedArray(uint8Array, byteOffset, featureTableJSONByteLength);
- var featureTableJson = JSON.parse(featureTableString);
- byteOffset += featureTableJSONByteLength;
- var featureTableBinary = new Uint8Array(arrayBuffer, byteOffset, featureTableBinaryByteLength);
- byteOffset += featureTableBinaryByteLength;
- var batchTableJson;
- var 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.
- var batchTableString = getStringFromTypedArray(uint8Array, byteOffset, batchTableJSONByteLength);
- batchTableJson = JSON.parse(batchTableString);
- 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);
- }
- }
- var numberOfBoxes = defaultValue(featureTableJson.BOXES_LENGTH, 0);
- var numberOfCylinders = defaultValue(featureTableJson.CYLINDERS_LENGTH, 0);
- var numberOfEllipsoids = defaultValue(featureTableJson.ELLIPSOIDS_LENGTH, 0);
- var numberOfSpheres = defaultValue(featureTableJson.SPHERES_LENGTH, 0);
- var totalPrimitives = numberOfBoxes + numberOfCylinders + numberOfEllipsoids + numberOfSpheres;
- var batchTable = new Cesium3DTileBatchTable(content, totalPrimitives, batchTableJson, batchTableBinary, createColorChangedCallback(content));
- content._batchTable = batchTable;
- if (totalPrimitives === 0) {
- return;
- }
- var modelMatrix = content.tile.computedTransform;
- var center;
- if (defined(featureTableJson.RTC_CENTER)) {
- center = Cartesian3.unpack(featureTableJson.RTC_CENTER);
- Matrix4.multiplyByPoint(modelMatrix, center, center);
- }
- var batchIds = getBatchIds(featureTableJson, featureTableBinary);
- if (numberOfBoxes > 0 || numberOfCylinders > 0 || numberOfEllipsoids > 0 || numberOfSpheres > 0) {
- var boxes;
- var cylinders;
- var ellipsoids;
- var spheres;
- if (numberOfBoxes > 0) {
- var boxesByteOffset = featureTableBinary.byteOffset + featureTableJson.BOXES.byteOffset;
- boxes = new Float32Array(featureTableBinary.buffer, boxesByteOffset, Vector3DTileGeometry.packedBoxLength * numberOfBoxes);
- }
- if (numberOfCylinders > 0) {
- var cylindersByteOffset = featureTableBinary.byteOffset + featureTableJson.CYLINDERS.byteOffset;
- cylinders = new Float32Array(featureTableBinary.buffer, cylindersByteOffset, Vector3DTileGeometry.packedCylinderLength * numberOfCylinders);
- }
- if (numberOfEllipsoids > 0) {
- var ellipsoidsByteOffset = featureTableBinary.byteOffset + featureTableJson.ELLIPSOIDS.byteOffset;
- ellipsoids = new Float32Array(featureTableBinary.buffer, ellipsoidsByteOffset, Vector3DTileGeometry.packedEllipsoidLength * numberOfEllipsoids);
- }
- if (numberOfSpheres > 0) {
- var 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) {
- var featuresLength = content.featuresLength;
- if (!defined(content._features) && (featuresLength > 0)) {
- var 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);
- var 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)) {
- var 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;
|