Flatlogic Bot 055d24df95 WORKING
2025-10-14 02:37:44 +00:00

168 lines
5.1 KiB
JavaScript

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;