@cesium/engine
Version:
CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.
141 lines (120 loc) • 4.31 kB
JavaScript
import Check from "../Core/Check.js";
import deprecationWarning from "../Core/deprecationWarning.js";
import getJsonFromTypedArray from "../Core/getJsonFromTypedArray.js";
import RuntimeError from "../Core/RuntimeError.js";
/**
* Handles parsing of an Instanced 3D Model.
*
* @namespace I3dmParser
* @private
*/
const I3dmParser = {};
I3dmParser._deprecationWarning = deprecationWarning;
const sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT;
/**
* Parses the contents of a {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification/TileFormats/Instanced3DModel|Instanced 3D Model}.
*
* @private
*
* @param {ArrayBuffer} arrayBuffer The array buffer containing the i3dm.
* @param {number} [byteOffset=0] The byte offset of the beginning of the i3dm in the array buffer.
* @returns {object} Returns an object with the glTF format, feature table (binary and json), batch table (binary and json) and glTF parts of the i3dm.
*/
I3dmParser.parse = function (arrayBuffer, byteOffset) {
//>>includeStart('debug', pragmas.debug);
Check.defined("arrayBuffer", arrayBuffer);
//>>includeEnd('debug');
const byteStart = byteOffset ?? 0;
byteOffset = byteStart;
const uint8Array = new Uint8Array(arrayBuffer);
const view = new DataView(arrayBuffer);
byteOffset += sizeOfUint32; // Skip magic
const version = view.getUint32(byteOffset, true);
if (version !== 1) {
throw new RuntimeError(
`Only Instanced 3D Model version 1 is supported. Version ${version} is not.`,
);
}
byteOffset += sizeOfUint32;
const byteLength = view.getUint32(byteOffset, true);
byteOffset += sizeOfUint32;
const featureTableJsonByteLength = view.getUint32(byteOffset, true);
if (featureTableJsonByteLength === 0) {
throw new RuntimeError(
"featureTableJsonByteLength is zero, the feature table must be defined.",
);
}
byteOffset += sizeOfUint32;
const featureTableBinaryByteLength = view.getUint32(byteOffset, true);
byteOffset += sizeOfUint32;
const batchTableJsonByteLength = view.getUint32(byteOffset, true);
byteOffset += sizeOfUint32;
const batchTableBinaryByteLength = view.getUint32(byteOffset, true);
byteOffset += sizeOfUint32;
const gltfFormat = view.getUint32(byteOffset, true);
if (gltfFormat !== 1 && gltfFormat !== 0) {
throw new RuntimeError(
`Only glTF format 0 (uri) or 1 (embedded) are supported. Format ${gltfFormat} is not.`,
);
}
byteOffset += sizeOfUint32;
const featureTableJson = getJsonFromTypedArray(
uint8Array,
byteOffset,
featureTableJsonByteLength,
);
byteOffset += featureTableJsonByteLength;
const featureTableBinary = new Uint8Array(
arrayBuffer,
byteOffset,
featureTableBinaryByteLength,
);
byteOffset += featureTableBinaryByteLength;
let batchTableJson;
let batchTableBinary;
if (batchTableJsonByteLength > 0) {
batchTableJson = getJsonFromTypedArray(
uint8Array,
byteOffset,
batchTableJsonByteLength,
);
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);
byteOffset += batchTableBinaryByteLength;
}
}
const gltfByteLength = byteStart + byteLength - byteOffset;
if (gltfByteLength === 0) {
throw new RuntimeError("glTF byte length must be greater than 0.");
}
let gltfView;
if (byteOffset % 4 === 0) {
gltfView = new Uint8Array(arrayBuffer, byteOffset, gltfByteLength);
} else {
// Create a copy of the glb so that it is 4-byte aligned
I3dmParser._deprecationWarning(
"i3dm-glb-unaligned",
"The embedded glb is not aligned to a 4-byte boundary.",
);
gltfView = new Uint8Array(
uint8Array.subarray(byteOffset, byteOffset + gltfByteLength),
);
}
return {
gltfFormat: gltfFormat,
featureTableJson: featureTableJson,
featureTableBinary: featureTableBinary,
batchTableJson: batchTableJson,
batchTableBinary: batchTableBinary,
gltf: gltfView,
};
};
export default I3dmParser;