UNPKG

cmpt

Version:

A TypeScript library for parsing and building B3DM (Batched 3D Model) files

78 lines (68 loc) 3.05 kB
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; }