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