123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- import Check from "../Core/Check.js";
- import DeveloperError from "../Core/DeveloperError.js";
- import defined from "../Core/defined.js";
- import getJsonFromTypedArray from "../Core/getJsonFromTypedArray.js";
- import MetadataTable from "./MetadataTable.js";
- /**
- * An object representing voxel content for a {@link Cesium3DTilesVoxelProvider}.
- *
- * @alias VoxelContent
- * @constructor
- *
- * @param {Resource} resource The resource for this voxel content. This is used for fetching external buffers as needed.
- *
- * @private
- * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
- */
- function VoxelContent(resource) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("resource", resource);
- //>>includeEnd('debug');
- this._resource = resource;
- this._metadataTable = undefined;
- }
- Object.defineProperties(VoxelContent.prototype, {
- /**
- * The {@link MetadataTable} storing voxel property values.
- *
- * @type {MetadataTable}
- * @readonly
- * @private
- */
- metadataTable: {
- get: function () {
- return this._metadataTable;
- },
- },
- });
- /**
- * Creates an object representing voxel content for a {@link Cesium3DTilesVoxelProvider}.
- *
- * @param {Resource} resource The resource for this voxel content. This is used for fetching external buffers as needed.
- * @param {object} [json] Voxel JSON contents. Mutually exclusive with binary.
- * @param {Uint8Array} [binary] Voxel binary contents. Mutually exclusive with json.
- * @param {MetadataSchema} metadataSchema The metadata schema used by property tables in the voxel content
- * @returns {Promise<VoxelContent>}
- *
- * @exception {DeveloperError} One of json and binary must be defined.
- */
- VoxelContent.fromJson = async function (
- resource,
- json,
- binary,
- metadataSchema
- ) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("resource", resource);
- if (defined(json) === defined(binary)) {
- throw new DeveloperError("One of json and binary must be defined.");
- }
- //>>includeEnd('debug');
- let chunks;
- if (defined(json)) {
- chunks = {
- json: json,
- binary: undefined,
- };
- } else {
- chunks = parseVoxelChunks(binary);
- }
- const buffersU8 = await requestBuffers(resource, chunks.json, chunks.binary);
- const bufferViewsU8 = {};
- const bufferViewsLength = chunks.json.bufferViews.length;
- for (let i = 0; i < bufferViewsLength; ++i) {
- const bufferViewJson = chunks.json.bufferViews[i];
- const start = bufferViewJson.byteOffset;
- const end = start + bufferViewJson.byteLength;
- const buffer = buffersU8[bufferViewJson.buffer];
- const bufferView = buffer.subarray(start, end);
- bufferViewsU8[i] = bufferView;
- }
- const propertyTableIndex = chunks.json.voxelTable;
- const propertyTableJson = chunks.json.propertyTables[propertyTableIndex];
- const content = new VoxelContent(resource);
- content._metadataTable = new MetadataTable({
- count: propertyTableJson.count,
- properties: propertyTableJson.properties,
- class: metadataSchema.classes[propertyTableJson.class],
- bufferViews: bufferViewsU8,
- });
- return content;
- };
- function requestBuffers(resource, json, binary) {
- const buffersLength = json.buffers.length;
- const bufferPromises = new Array(buffersLength);
- for (let i = 0; i < buffersLength; i++) {
- const buffer = json.buffers[i];
- if (defined(buffer.uri)) {
- const baseResource = resource;
- const bufferResource = baseResource.getDerivedResource({
- url: buffer.uri,
- });
- bufferPromises[i] = bufferResource
- .fetchArrayBuffer()
- .then(function (arrayBuffer) {
- return new Uint8Array(arrayBuffer);
- });
- } else {
- bufferPromises[i] = Promise.resolve(binary);
- }
- }
- return Promise.all(bufferPromises);
- }
- /**
- * A helper object for storing the two parts of the binary voxel content
- *
- * @typedef {object} VoxelChunks
- * @property {object} json The json chunk of the binary voxel content
- * @property {Uint8Array} binary The binary chunk of the binary voxel content. This represents the internal buffer.
- * @private
- */
- /**
- * Given binary voxel content, split into JSON and binary chunks
- *
- * @param {Uint8Array} binaryView The binary voxel content
- * @returns {VoxelChunks} An object containing the JSON and binary chunks
- * @private
- */
- function parseVoxelChunks(binaryView) {
- // Parse the header
- const littleEndian = true;
- const reader = new DataView(binaryView.buffer, binaryView.byteOffset);
- // Skip to the chunk lengths
- let byteOffset = 8;
- // Read the bottom 32 bits of the 64-bit byte length. This is ok for now because:
- // 1) not all browsers have native 64-bit operations
- // 2) the data is well under 4GB
- const jsonByteLength = reader.getUint32(byteOffset, littleEndian);
- byteOffset += 8;
- const binaryByteLength = reader.getUint32(byteOffset, littleEndian);
- byteOffset += 8;
- const json = getJsonFromTypedArray(binaryView, byteOffset, jsonByteLength);
- byteOffset += jsonByteLength;
- const binary = binaryView.subarray(byteOffset, byteOffset + binaryByteLength);
- return {
- json: json,
- binary: binary,
- };
- }
- export default VoxelContent;
|