cmpt
Version:
A TypeScript library for parsing and building B3DM (Batched 3D Model) files
69 lines (57 loc) • 2.57 kB
text/typescript
import { B3dmData, B3dmHeader } from './types';
/**
* 解析B3DM二进制数据
* @param arrayBuffer B3DM文件的ArrayBuffer
* @returns 解析后的B3DM数据结构
*/
export function parseB3dm(arrayBuffer: ArrayBuffer): B3dmData {
const dataView = new DataView(arrayBuffer);
let offset = 0;
// 1. 解析文件头(28字节)
const header: B3dmHeader = {} as B3dmHeader;
header.magic = String.fromCharCode(
dataView.getUint8(offset++),
dataView.getUint8(offset++),
dataView.getUint8(offset++),
dataView.getUint8(offset++)
);
header.version = dataView.getUint32(offset, true); offset += 4;
header.byteLength = dataView.getUint32(offset, true); offset += 4;
header.featureTableJSONByteLength = dataView.getUint32(offset, true); offset += 4;
header.featureTableBinaryByteLength = dataView.getUint32(offset, true); offset += 4;
header.batchTableJSONByteLength = dataView.getUint32(offset, true); offset += 4;
header.batchTableBinaryByteLength = dataView.getUint32(offset, true); offset += 4;
// 校验文件标识
if (header.magic !== 'b3dm') {
throw new Error('Invalid B3DM file: magic number mismatch');
}
// 2. 解析特征表
const featureTableJSON = JSON.parse(
new TextDecoder().decode(
new Uint8Array(arrayBuffer.slice(offset, offset + header.featureTableJSONByteLength))
)
);
offset += header.featureTableJSONByteLength;
const featureTableBinary = header.featureTableBinaryByteLength > 0
? new Uint8Array(arrayBuffer.slice(offset, offset + header.featureTableBinaryByteLength))
: undefined;
offset += header.featureTableBinaryByteLength;
// 3. 解析批量表(可选)
let batchTable = undefined;
if (header.batchTableJSONByteLength > 0) {
const batchTableJSON = JSON.parse(
new TextDecoder().decode(
new Uint8Array(arrayBuffer.slice(offset, offset + header.batchTableJSONByteLength))
)
);
offset += header.batchTableJSONByteLength;
const batchTableBinary = header.batchTableBinaryByteLength > 0
? new Uint8Array(arrayBuffer.slice(offset, offset + header.batchTableBinaryByteLength))
: undefined;
offset += header.batchTableBinaryByteLength;
batchTable = { json: batchTableJSON, binary: batchTableBinary };
}
// 4. 提取GLB数据(剩余部分)
const glbData = new Uint8Array(arrayBuffer.slice(offset));
return { header, featureTable: { json: featureTableJSON, binary: featureTableBinary }, batchTable, glbData };
}