cmpt
Version:
A TypeScript library for parsing and building B3DM (Batched 3D Model) files
78 lines (68 loc) • 3.05 kB
text/typescript
import { B3dmBuildOptions, B3dmHeader } from './types';
/**
* 构建B3DM二进制数据
* @param options 构建选项(包含GLB和元数据)
* @returns B3DM的ArrayBuffer
*/
export function buildB3dm(options: B3dmBuildOptions): ArrayBuffer {
const {
glbData,
featureTableJSON = {},
featureTableBinary = new Uint8Array(0),
batchTableJSON = {},
batchTableBinary = new Uint8Array(0),
} = options;
// 1. 计算各部分长度
const featureTableJSONStr = JSON.stringify(featureTableJSON);
const featureTableJSONByteLength = new TextEncoder().encode(featureTableJSONStr).length;
const featureTableBinaryByteLength = featureTableBinary.byteLength;
const batchTableJSONStr = Object.keys(batchTableJSON).length > 0 ? JSON.stringify(batchTableJSON) : '';
const batchTableJSONByteLength = new TextEncoder().encode(batchTableJSONStr).length;
const batchTableBinaryByteLength = batchTableBinary.byteLength;
const glbByteLength = glbData.byteLength;
// 2. 计算文件总长度(头28字节 + 各部分长度)
const totalByteLength = 28 + featureTableJSONByteLength + featureTableBinaryByteLength + batchTableJSONByteLength + batchTableBinaryByteLength + glbByteLength;
// 3. 构建文件头
const header: B3dmHeader = {
magic: 'b3dm',
version: 1,
byteLength: totalByteLength,
featureTableJSONByteLength,
featureTableBinaryByteLength,
batchTableJSONByteLength,
batchTableBinaryByteLength,
};
// 4. 写入二进制数据
const arrayBuffer = new ArrayBuffer(totalByteLength);
const dataView = new DataView(arrayBuffer);
let offset = 0;
// 写入文件头(28字节)
for (const char of header.magic) {
dataView.setUint8(offset++, char.charCodeAt(0));
}
dataView.setUint32(offset, header.version, true); offset += 4;
dataView.setUint32(offset, header.byteLength, true); offset += 4;
dataView.setUint32(offset, header.featureTableJSONByteLength, true); offset += 4;
dataView.setUint32(offset, header.featureTableBinaryByteLength, true); offset += 4;
dataView.setUint32(offset, header.batchTableJSONByteLength, true); offset += 4;
dataView.setUint32(offset, header.batchTableBinaryByteLength, true); offset += 4;
// 写入特征表
new Uint8Array(arrayBuffer).set(new TextEncoder().encode(featureTableJSONStr), offset);
offset += featureTableJSONByteLength;
if (featureTableBinaryByteLength > 0) {
new Uint8Array(arrayBuffer).set(featureTableBinary, offset);
offset += featureTableBinaryByteLength;
}
// 写入批量表
if (batchTableJSONByteLength > 0) {
new Uint8Array(arrayBuffer).set(new TextEncoder().encode(batchTableJSONStr), offset);
offset += batchTableJSONByteLength;
}
if (batchTableBinaryByteLength > 0) {
new Uint8Array(arrayBuffer).set(batchTableBinary, offset);
offset += batchTableBinaryByteLength;
}
// 写入GLB数据
new Uint8Array(arrayBuffer).set(glbData, offset);
return arrayBuffer;
}