b3dm
Version: 
A TypeScript library for parsing and building B3DM (Batched 3D Model) files
195 lines (190 loc) • 7.19 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// package.json
var require_package = __commonJS({
  "package.json"(exports2, module2) {
    module2.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/index.ts
var index_exports = {};
__export(index_exports, {
  buildB3dm: () => buildB3dm,
  parseB3dm: () => parseB3dm,
  version: () => version
});
module.exports = __toCommonJS(index_exports);
// 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;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  buildB3dm,
  parseB3dm,
  version
});
//# sourceMappingURL=index.js.map