| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- import Cartesian3 from "../Core/Cartesian3.js";
- import Check from "../Core/Check.js";
- import defined from "../Core/defined.js";
- import MetadataType from "./MetadataType.js";
- import OrientedBoundingBox from "../Core/OrientedBoundingBox.js";
-
- /**
- * A cell from a {@link VoxelPrimitive}.
- * <p>
- * Provides access to properties associated with one cell of a voxel primitive.
- * </p>
- * <p>
- * Do not construct this directly. Access it through picking using {@link Scene#pickVoxel}.
- * </p>
- *
- * @alias VoxelCell
- * @constructor
- *
- * @param {VoxelPrimitive} primitive The voxel primitive containing the cell
- * @param {number} tileIndex The index of the tile
- * @param {number} sampleIndex The index of the sample within the tile, containing metadata for this cell
- *
- * @example
- * // On left click, display all the properties for a voxel cell in the console log.
- * handler.setInputAction(function(movement) {
- * const voxelCell = scene.pickVoxel(movement.position);
- * if (voxelCell instanceof Cesium.VoxelCell) {
- * const propertyIds = voxelCell.getPropertyIds();
- * const length = propertyIds.length;
- * for (let i = 0; i < length; ++i) {
- * const propertyId = propertyIds[i];
- * console.log(`{propertyId}: ${voxelCell.getProperty(propertyId)}`);
- * }
- * }
- * }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
- *
- * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
- */
- function VoxelCell(primitive, tileIndex, sampleIndex) {
- this._primitive = primitive;
- this._tileIndex = tileIndex;
- this._sampleIndex = sampleIndex;
- this._metadata = {};
- this._orientedBoundingBox = new OrientedBoundingBox();
- }
-
- /**
- * Construct a VoxelCell, and update the metadata and bounding box using the properties
- * of a supplied keyframe node.
- *
- * @private
- * @param {VoxelPrimitive} primitive The voxel primitive containing the cell.
- * @param {number} tileIndex The index of the tile.
- * @param {number} sampleIndex The index of the sample within the tile, containing metadata for this cell.
- * @param {KeyframeNode} keyframeNode The keyframe node containing information about the tile.
- * @returns {VoxelCell}
- *
- * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
- */
- VoxelCell.fromKeyframeNode = function (
- primitive,
- tileIndex,
- sampleIndex,
- keyframeNode,
- ) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("primitive", primitive);
- Check.typeOf.number("tileIndex", tileIndex);
- Check.typeOf.number("sampleIndex", sampleIndex);
- Check.typeOf.object("keyframeNode", keyframeNode);
- //>>includeEnd('debug');
-
- const voxelCell = new VoxelCell(primitive, tileIndex, sampleIndex);
- const { spatialNode, content } = keyframeNode;
- voxelCell._metadata = getMetadataForSample(primitive, content, sampleIndex);
- voxelCell._orientedBoundingBox = getOrientedBoundingBox(
- primitive,
- spatialNode,
- sampleIndex,
- voxelCell._orientedBoundingBox,
- );
- return voxelCell;
- };
-
- /**
- * @private
- * @param {VoxelPrimitive} primitive
- * @param {VoxelContent} content
- * @param {number} sampleIndex
- * @returns {object}
- */
- function getMetadataForSample(primitive, content, sampleIndex) {
- if (!defined(content) || !defined(content.metadata)) {
- return undefined;
- }
- const { names, types } = primitive.provider;
- const { metadata } = content;
- const metadataMap = {};
- for (let i = 0; i < names.length; i++) {
- const name = names[i];
- const componentCount = MetadataType.getComponentCount(types[i]);
- const samples = metadata[i].slice(
- sampleIndex * componentCount,
- (sampleIndex + 1) * componentCount,
- );
- metadataMap[name] = samples;
- }
- return metadataMap;
- }
-
- const tileCoordinateScratch = new Cartesian3();
- const tileUvScratch = new Cartesian3();
-
- /**
- * @private
- * @param {VoxelPrimitive} primitive
- * @param {SpatialNode} spatialNode
- * @param {OrientedBoundingBox} result
- * @returns {OrientedBoundingBox}
- */
- function getOrientedBoundingBox(primitive, spatialNode, sampleIndex, result) {
- // Convert the sample index into a 3D tile coordinate
- // Note: dimensions from the spatialNode include padding
- const paddedDimensions = spatialNode.dimensions;
- const sliceSize = paddedDimensions.x * paddedDimensions.y;
- const zIndex = Math.floor(sampleIndex / sliceSize);
- const indexInSlice = sampleIndex - zIndex * sliceSize;
- const yIndex = Math.floor(indexInSlice / paddedDimensions.x);
- const xIndex = indexInSlice - yIndex * paddedDimensions.x;
- const tileCoordinate = Cartesian3.fromElements(
- xIndex,
- yIndex,
- zIndex,
- tileCoordinateScratch,
- );
-
- // Remove padding, and convert to a fraction in [0, 1], where the limits are
- // the unpadded bounds of the tile
- const tileUv = Cartesian3.divideComponents(
- Cartesian3.subtract(
- tileCoordinate,
- primitive._paddingBefore,
- tileCoordinateScratch,
- ),
- primitive.dimensions,
- tileUvScratch,
- );
-
- const shape = primitive._shape;
- return shape.computeOrientedBoundingBoxForSample(
- spatialNode,
- primitive.dimensions,
- tileUv,
- result,
- );
- }
-
- Object.defineProperties(VoxelCell.prototype, {
- /**
- * Gets an object of the metadata values for this cell. The object's keys are the metadata names.
- *
- * @memberof VoxelCell.prototype
- *
- * @type {object}
- *
- * @readonly
- * @private
- */
- metadata: {
- get: function () {
- return this._metadata;
- },
- },
-
- /**
- * All objects returned by {@link Scene#pick} have a <code>primitive</code> property. This returns
- * the VoxelPrimitive containing the cell.
- *
- * @memberof VoxelCell.prototype
- *
- * @type {VoxelPrimitive}
- *
- * @readonly
- */
- primitive: {
- get: function () {
- return this._primitive;
- },
- },
-
- /**
- * Get the sample index of the cell.
- *
- * @memberof VoxelCell.prototype
- *
- * @type {number}
- *
- * @readonly
- */
- sampleIndex: {
- get: function () {
- return this._sampleIndex;
- },
- },
-
- /**
- * Get the index of the tile containing the cell.
- *
- * @memberof VoxelCell.prototype
- *
- * @type {number}
- *
- * @readonly
- */
- tileIndex: {
- get: function () {
- return this._tileIndex;
- },
- },
-
- /**
- * Get a copy of the oriented bounding box containing the cell.
- *
- * @memberof VoxelCell.prototype
- *
- * @type {OrientedBoundingBox}
- *
- * @readonly
- */
- orientedBoundingBox: {
- get: function () {
- return this._orientedBoundingBox.clone();
- },
- },
- });
-
- /**
- * Returns <code>true</code> if the feature contains this property.
- *
- * @param {string} name The case-sensitive name of the property.
- * @returns {boolean} Whether the feature contains this property.
- */
- VoxelCell.prototype.hasProperty = function (name) {
- return defined(this._metadata[name]);
- };
-
- /**
- * Returns an array of metadata property names for the feature.
- *
- * @returns {string[]} The IDs of the feature's properties.
- */
- VoxelCell.prototype.getNames = function () {
- return Object.keys(this._metadata);
- };
-
- /**
- * Returns a copy of the value of the metadata in the cell with the given name.
- *
- * @param {string} name The case-sensitive name of the property.
- * @returns {*} The value of the property or <code>undefined</code> if the feature does not have this property.
- *
- * @example
- * // Display all the properties for a voxel cell in the console log.
- * const names = voxelCell.getNames();
- * for (let i = 0; i < names.length; ++i) {
- * const name = names[i];
- * console.log(`{name}: ${voxelCell.getProperty(name)}`);
- * }
- */
- VoxelCell.prototype.getProperty = function (name) {
- return this._metadata[name];
- };
-
- export default VoxelCell;
|