Add existing to tracked
This commit is contained in:
+274
@@ -0,0 +1,274 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user