b3dm
Version:
A TypeScript library for parsing and building B3DM (Batched 3D Model) files
168 lines (164 loc) • 6.16 kB
JavaScript
var __getOwnPropNames = Object.getOwnPropertyNames;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
// package.json
var require_package = __commonJS({
"package.json"(exports, module) {
module.exports = {
name: "b3dm",
version: "0.1.1",
description: "A TypeScript library for parsing and building B3DM (Batched 3D Model) files",
main: "dist/index.cjs",
module: "dist/index.js",
types: "dist/index.d.ts",
exports: {
".": {
import: "./dist/index.js",
require: "./dist/index.cjs",
types: "./dist/index.d.ts"
}
},
scripts: {
build: "tsup",
prepublishOnly: "npm run build",
test: 'echo "Error: no test specified" && exit 1'
},
keywords: ["b3dm", "3d-tiles", "gltf", "3d", "geospatial", "typescript"],
author: "Your Name",
license: "MIT",
homepage: "https://github.com/your-username/b3dm-ts",
repository: {
type: "git",
url: "git+https://github.com/your-username/b3dm-ts.git"
},
bugs: {
url: "https://github.com/your-username/b3dm-ts/issues"
},
devDependencies: {
"@types/node": "^20.0.0",
rimraf: "^5.0.0",
tsup: "^8.0.0",
typescript: "^5.0.0"
}
};
}
});
// src/parser.ts
function parseB3dm(arrayBuffer) {
const dataView = new DataView(arrayBuffer);
let offset = 0;
const header = {};
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");
}
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)) : void 0;
offset += header.featureTableBinaryByteLength;
let batchTable = void 0;
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)) : void 0;
offset += header.batchTableBinaryByteLength;
batchTable = { json: batchTableJSON, binary: batchTableBinary };
}
const glbData = new Uint8Array(arrayBuffer.slice(offset));
return { header, featureTable: { json: featureTableJSON, binary: featureTableBinary }, batchTable, glbData };
}
// src/builder.ts
function buildB3dm(options) {
const {
glbData,
featureTableJSON = {},
featureTableBinary = new Uint8Array(0),
batchTableJSON = {},
batchTableBinary = new Uint8Array(0)
} = options;
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;
const totalByteLength = 28 + featureTableJSONByteLength + featureTableBinaryByteLength + batchTableJSONByteLength + batchTableBinaryByteLength + glbByteLength;
const header = {
magic: "b3dm",
version: 1,
byteLength: totalByteLength,
featureTableJSONByteLength,
featureTableBinaryByteLength,
batchTableJSONByteLength,
batchTableBinaryByteLength
};
const arrayBuffer = new ArrayBuffer(totalByteLength);
const dataView = new DataView(arrayBuffer);
let offset = 0;
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;
}
new Uint8Array(arrayBuffer).set(glbData, offset);
return arrayBuffer;
}
// src/index.ts
var version = require_package().version;
export {
buildB3dm,
parseB3dm,
version
};
//# sourceMappingURL=index.mjs.map