@kitware/vtk.js
Version:
Visualization Toolkit for the Web
70 lines (67 loc) • 2.37 kB
JavaScript
import BinaryHelper from '../../Core/BinaryHelper.js';
import { BINARY_HEADER_MAGIC, BINARY_CHUNK_TYPES, BINARY_CHUNK_HEADER_INTS, BINARY_HEADER_LENGTH, BINARY_HEADER_INTS } from './Constants.js';
function getChunkInfo(headerStart, data) {
const header = new Uint32Array(data, headerStart, BINARY_CHUNK_HEADER_INTS);
const chunkStart = headerStart + BINARY_CHUNK_HEADER_INTS * 4;
const chunkLength = header[0];
const chunkType = header[1];
return {
start: chunkStart,
length: chunkLength,
type: chunkType
};
}
function getAllChunkInfos(data) {
const infos = [];
let chunkStart = BINARY_HEADER_INTS * 4;
while (chunkStart < data.byteLength) {
const chunkInfo = getChunkInfo(chunkStart, data);
infos.push(chunkInfo);
chunkStart += chunkInfo.length + BINARY_CHUNK_HEADER_INTS * 4;
}
return infos;
}
function getJsonFromChunk(chunkInfo, data) {
const chunkLength = chunkInfo.length;
const jsonStart = (BINARY_HEADER_INTS + BINARY_CHUNK_HEADER_INTS) * 4;
const jsonSlice = new Uint8Array(data, jsonStart, chunkLength);
const stringBuffer = BinaryHelper.arrayBufferToString(jsonSlice);
return JSON.parse(stringBuffer);
}
function getBufferFromChunk(chunkInfo, data) {
return data.slice(chunkInfo.start, chunkInfo.start + chunkInfo.length);
}
function parseGLB(data) {
let json;
const buffers = [];
const headerView = new DataView(data, 0, BINARY_HEADER_LENGTH);
const header = {
magic: BinaryHelper.arrayBufferToString(new Uint8Array(data, 0, 4)),
version: headerView.getUint32(4, true),
length: headerView.getUint32(8, true)
};
if (header.magic !== BINARY_HEADER_MAGIC) {
throw new Error('Unsupported glTF-Binary header.');
} else if (header.version < 2.0) {
throw new Error('Unsupported legacy binary file detected.');
}
const chunkInfos = getAllChunkInfos(data);
chunkInfos.forEach(chunkInfo => {
if (chunkInfo.type === BINARY_CHUNK_TYPES.JSON && !json) {
json = getJsonFromChunk(chunkInfo, data);
} else if (chunkInfo.type === BINARY_CHUNK_TYPES.BIN) {
buffers.push(getBufferFromChunk(chunkInfo, data));
}
});
if (!json) {
throw new Error('glTF-Binary: JSON content not found.');
}
if (!buffers) {
throw new Error('glTF-Binary: Binary chunk not found.');
}
return {
json,
buffers
};
}
export { parseGLB as default };