UNPKG

@loaders.gl/draco

Version:

Framework-independent loader and writer for Draco compressed meshes and point clouds

1,323 lines (1,305 loc) 489 kB
(function webpackUniversalModuleDefinition(root, factory) { if (typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if (typeof define === 'function' && define.amd) define([], factory); else if (typeof exports === 'object') exports['loaders'] = factory(); else root['loaders'] = factory();})(globalThis, function () { "use strict"; var __exports__ = (() => { var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; 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 __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // external-global-plugin:@loaders.gl/core var require_core = __commonJS({ "external-global-plugin:@loaders.gl/core"(exports, module) { module.exports = globalThis.loaders; } }); // bundle.ts var bundle_exports = {}; __export(bundle_exports, { DRACO_EXTERNAL_LIBRARIES: () => DRACO_EXTERNAL_LIBRARIES, DRACO_EXTERNAL_LIBRARY_URLS: () => DRACO_EXTERNAL_LIBRARY_URLS, DracoArrowLoader: () => DracoArrowLoader, DracoLoader: () => DracoLoader, DracoWorkerLoader: () => DracoWorkerLoader, DracoWriter: () => DracoWriter, DracoWriterWorker: () => DracoWriterWorker }); __reExport(bundle_exports, __toESM(require_core(), 1)); // ../worker-utils/src/lib/npm-tag.ts var NPM_TAG = "latest"; // ../worker-utils/src/lib/env-utils/version.ts var warningIssued = false; function getVersion() { if (!globalThis._loadersgl_?.version) { globalThis._loadersgl_ = globalThis._loadersgl_ || {}; if (typeof __VERSION__ === "undefined" && !warningIssued) { console.warn( "loaders.gl: The __VERSION__ variable is not injected using babel plugin. Latest unstable workers would be fetched from the CDN." ); globalThis._loadersgl_.version = NPM_TAG; warningIssued = true; } else { globalThis._loadersgl_.version = __VERSION__; } } return globalThis._loadersgl_.version; } var VERSION = getVersion(); // ../worker-utils/src/lib/env-utils/assert.ts function assert(condition, message) { if (!condition) { throw new Error(message || "loaders.gl assertion failed."); } } // ../worker-utils/src/lib/env-utils/globals.ts var globals = { self: typeof self !== "undefined" && self, window: typeof window !== "undefined" && window, global: typeof global !== "undefined" && global, document: typeof document !== "undefined" && document }; var self_ = globals.self || globals.window || globals.global || {}; var window_ = globals.window || globals.self || globals.global || {}; var global_ = globals.global || globals.self || globals.window || {}; var document_ = globals.document || {}; var isBrowser = ( // @ts-ignore process.browser typeof process !== "object" || String(process) !== "[object process]" || process.browser ); var isWorker = typeof importScripts === "function"; var isMobile = typeof window !== "undefined" && typeof window.orientation !== "undefined"; var matches = typeof process !== "undefined" && process.version && /v([0-9]*)/.exec(process.version); var nodeVersion = matches && parseFloat(matches[1]) || 0; // ../worker-utils/src/lib/library-utils/library-utils.ts var loadLibraryPromises = {}; function extractLoadLibraryOptions(options = {}) { const useLocalLibraries = options.useLocalLibraries ?? options.core?.useLocalLibraries; const CDN = options.CDN ?? options.core?.CDN; const modules = options.modules; return { ...useLocalLibraries !== void 0 ? { useLocalLibraries } : {}, ...CDN !== void 0 ? { CDN } : {}, ...modules !== void 0 ? { modules } : {} }; } async function loadLibrary(libraryUrl, moduleName = null, options = {}, libraryName = null) { if (moduleName) { libraryUrl = getLibraryUrl(libraryUrl, moduleName, options, libraryName); } loadLibraryPromises[libraryUrl] = // eslint-disable-next-line @typescript-eslint/no-misused-promises loadLibraryPromises[libraryUrl] || loadLibraryFromFile(libraryUrl); return await loadLibraryPromises[libraryUrl]; } function getLibraryUrl(library, moduleName, options = {}, libraryName = null) { if (options?.core) { throw new Error("loadLibrary: options.core must be pre-normalized"); } if (!options.useLocalLibraries && library.startsWith("http")) { return library; } libraryName = libraryName || library; const modules = options.modules || {}; if (modules[libraryName]) { return modules[libraryName]; } if (!isBrowser) { return `modules/${moduleName}/dist/libs/${libraryName}`; } if (options.CDN) { assert(options.CDN.startsWith("http")); return `${options.CDN}/${moduleName}@${VERSION}/dist/libs/${libraryName}`; } if (isWorker) { return `../src/libs/${libraryName}`; } return `modules/${moduleName}/src/libs/${libraryName}`; } async function loadLibraryFromFile(libraryUrl) { if (libraryUrl.endsWith("wasm")) { return await loadAsArrayBuffer(libraryUrl); } if (!isBrowser) { const { requireFromFile } = globalThis.loaders || {}; try { const result = await requireFromFile?.(libraryUrl); if (result || !libraryUrl.includes("/dist/libs/")) { return result; } return await requireFromFile?.(libraryUrl.replace("/dist/libs/", "/src/libs/")); } catch (error) { if (libraryUrl.includes("/dist/libs/")) { try { return await requireFromFile?.(libraryUrl.replace("/dist/libs/", "/src/libs/")); } catch { } } console.error(error); return null; } } if (isWorker) { return importScripts(libraryUrl); } const scriptSource = await loadAsText(libraryUrl); return loadLibraryFromString(scriptSource, libraryUrl); } function loadLibraryFromString(scriptSource, id) { if (!isBrowser) { const { requireFromString } = globalThis.loaders || {}; return requireFromString?.(scriptSource, id); } if (isWorker) { eval.call(globalThis, scriptSource); return null; } const script = document.createElement("script"); script.id = id; try { script.appendChild(document.createTextNode(scriptSource)); } catch (e) { script.text = scriptSource; } document.body.appendChild(script); return null; } async function loadAsArrayBuffer(url) { const { readFileAsArrayBuffer } = globalThis.loaders || {}; if (isBrowser || !readFileAsArrayBuffer || url.startsWith("http")) { const response = await fetch(url); return await response.arrayBuffer(); } try { return await readFileAsArrayBuffer(url); } catch { if (url.includes("/dist/libs/")) { return await readFileAsArrayBuffer(url.replace("/dist/libs/", "/src/libs/")); } throw new Error(`Failed to load ArrayBuffer from ${url}`); } } async function loadAsText(url) { const { readFileAsText } = globalThis.loaders || {}; if (isBrowser || !readFileAsText || url.startsWith("http")) { const response = await fetch(url); return await response.text(); } try { return await readFileAsText(url); } catch { if (url.includes("/dist/libs/")) { return await readFileAsText(url.replace("/dist/libs/", "/src/libs/")); } throw new Error(`Failed to load text from ${url}`); } } // src/lib/draco-module-loader.ts var DRACO_DECODER_VERSION = "1.5.6"; var DRACO_ENCODER_VERSION = "1.4.1"; var STATIC_DECODER_URL = `https://www.gstatic.com/draco/versioned/decoders/${DRACO_DECODER_VERSION}`; var DRACO_EXTERNAL_LIBRARIES = { /** The primary Draco3D encoder, javascript wrapper part */ DECODER: "draco_wasm_wrapper.js", /** The primary draco decoder, compiled web assembly part */ DECODER_WASM: "draco_decoder.wasm", /** Fallback decoder for non-webassebly environments. Very big bundle, lower performance */ FALLBACK_DECODER: "draco_decoder.js", /** Draco encoder */ ENCODER: "draco_encoder.js" }; var DRACO_EXTERNAL_LIBRARY_URLS = { [DRACO_EXTERNAL_LIBRARIES.DECODER]: `${STATIC_DECODER_URL}/${DRACO_EXTERNAL_LIBRARIES.DECODER}`, [DRACO_EXTERNAL_LIBRARIES.DECODER_WASM]: `${STATIC_DECODER_URL}/${DRACO_EXTERNAL_LIBRARIES.DECODER_WASM}`, [DRACO_EXTERNAL_LIBRARIES.FALLBACK_DECODER]: `${STATIC_DECODER_URL}/${DRACO_EXTERNAL_LIBRARIES.FALLBACK_DECODER}`, [DRACO_EXTERNAL_LIBRARIES.ENCODER]: `https://raw.githubusercontent.com/google/draco/${DRACO_ENCODER_VERSION}/javascript/${DRACO_EXTERNAL_LIBRARIES.ENCODER}` }; var loadDecoderPromise; var loadEncoderPromise; async function loadDracoDecoderModule(options = {}, type) { const modules = options.modules || {}; if (modules.draco3d) { loadDecoderPromise ||= modules.draco3d.createDecoderModule({}).then((draco) => { return { draco }; }); } else { loadDecoderPromise ||= loadDracoDecoder(options, type); } return await loadDecoderPromise; } async function loadDracoEncoderModule(options) { const modules = options.modules || {}; if (modules.draco3d) { loadEncoderPromise ||= modules.draco3d.createEncoderModule({}).then((draco) => { return { draco }; }); } else { loadEncoderPromise ||= loadDracoEncoder(options); } return await loadEncoderPromise; } function getLibraryExport(library, exportName) { if (library && typeof library === "object") { if (library.default) { return library.default; } if (library[exportName]) { return library[exportName]; } } return library; } async function loadDracoDecoder(options, type) { let DracoDecoderModule; let wasmBinary; switch (type) { case "js": DracoDecoderModule = await loadLibrary( DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.FALLBACK_DECODER], "draco", options, DRACO_EXTERNAL_LIBRARIES.FALLBACK_DECODER ); break; case "wasm": default: try { [DracoDecoderModule, wasmBinary] = await Promise.all([ await loadLibrary( DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.DECODER], "draco", options, DRACO_EXTERNAL_LIBRARIES.DECODER ), await loadLibrary( DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.DECODER_WASM], "draco", options, DRACO_EXTERNAL_LIBRARIES.DECODER_WASM ) ]); } catch { DracoDecoderModule = null; wasmBinary = null; } } DracoDecoderModule = getLibraryExport(DracoDecoderModule, "DracoDecoderModule"); DracoDecoderModule = DracoDecoderModule || globalThis.DracoDecoderModule; if (!DracoDecoderModule && !isBrowser) { [DracoDecoderModule, wasmBinary] = await Promise.all([ await loadLibrary( DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.DECODER], "draco", { ...options, useLocalLibraries: true }, DRACO_EXTERNAL_LIBRARIES.DECODER ), await loadLibrary( DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.DECODER_WASM], "draco", { ...options, useLocalLibraries: true }, DRACO_EXTERNAL_LIBRARIES.DECODER_WASM ) ]); DracoDecoderModule = getLibraryExport(DracoDecoderModule, "DracoDecoderModule"); DracoDecoderModule = DracoDecoderModule || globalThis.DracoDecoderModule; } return await initializeDracoDecoder(DracoDecoderModule, wasmBinary); } function initializeDracoDecoder(DracoDecoderModule, wasmBinary) { if (typeof DracoDecoderModule !== "function") { throw new Error("DracoDecoderModule could not be loaded"); } const options = {}; if (wasmBinary) { options.wasmBinary = wasmBinary; } return new Promise((resolve) => { DracoDecoderModule({ ...options, onModuleLoaded: (draco) => resolve({ draco }) // Module is Promise-like. Wrap in object to avoid loop. }); }); } async function loadDracoEncoder(options) { let DracoEncoderModule = await loadLibrary( DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.ENCODER], "draco", options, DRACO_EXTERNAL_LIBRARIES.ENCODER ); DracoEncoderModule = getLibraryExport(DracoEncoderModule, "DracoEncoderModule"); DracoEncoderModule = DracoEncoderModule || globalThis.DracoEncoderModule; if (!DracoEncoderModule && !isBrowser) { DracoEncoderModule = await loadLibrary( DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.ENCODER], "draco", { ...options, useLocalLibraries: true }, DRACO_EXTERNAL_LIBRARIES.ENCODER ); DracoEncoderModule = getLibraryExport(DracoEncoderModule, "DracoEncoderModule"); DracoEncoderModule = DracoEncoderModule || globalThis.DracoEncoderModule; } if (typeof DracoEncoderModule !== "function") { throw new Error("DracoEncoderModule could not be loaded"); } return new Promise((resolve) => { DracoEncoderModule({ onModuleLoaded: (draco) => resolve({ draco }) // Module is Promise-like. Wrap in object to avoid loop. }); }); } // src/lib/draco-builder.ts var GLTF_TO_DRACO_ATTRIBUTE_NAME_MAP = { POSITION: "POSITION", NORMAL: "NORMAL", COLOR_0: "COLOR", TEXCOORD_0: "TEX_COORD" }; var noop = () => { }; var DracoBuilder = class { draco; dracoEncoder; dracoMeshBuilder; dracoMetadataBuilder; log; // draco - the draco decoder, either import `draco3d` or load dynamically constructor(draco) { this.draco = draco; this.dracoEncoder = new this.draco.Encoder(); this.dracoMeshBuilder = new this.draco.MeshBuilder(); this.dracoMetadataBuilder = new this.draco.MetadataBuilder(); } destroy() { this.destroyEncodedObject(this.dracoMeshBuilder); this.destroyEncodedObject(this.dracoEncoder); this.destroyEncodedObject(this.dracoMetadataBuilder); this.dracoMeshBuilder = null; this.dracoEncoder = null; this.draco = null; } // TBD - when does this need to be called? destroyEncodedObject(object) { if (object) { this.draco.destroy(object); } } /** * Encode mesh or point cloud * @param mesh =({}) * @param options */ encodeSync(mesh, options = {}) { this.log = noop; this._setOptions(options); return options.pointcloud ? this._encodePointCloud(mesh, options) : this._encodeMesh(mesh, options); } // PRIVATE _getAttributesFromMesh(mesh) { const attributes = { ...mesh, ...mesh.attributes }; if (mesh.indices) { attributes.indices = mesh.indices; } return attributes; } _encodePointCloud(pointcloud, options) { const dracoPointCloud = new this.draco.PointCloud(); if (options.metadata) { this._addGeometryMetadata(dracoPointCloud, options.metadata); } const attributes = this._getAttributesFromMesh(pointcloud); this._createDracoPointCloud(dracoPointCloud, attributes, options); const dracoData = new this.draco.DracoInt8Array(); try { const encodedLen = this.dracoEncoder.EncodePointCloudToDracoBuffer( dracoPointCloud, false, dracoData ); if (!(encodedLen > 0)) { throw new Error("Draco encoding failed."); } this.log(`DRACO encoded ${dracoPointCloud.num_points()} points with ${dracoPointCloud.num_attributes()} attributes into ${encodedLen} bytes`); return dracoInt8ArrayToArrayBuffer(dracoData); } finally { this.destroyEncodedObject(dracoData); this.destroyEncodedObject(dracoPointCloud); } } _encodeMesh(mesh, options) { const dracoMesh = new this.draco.Mesh(); if (options.metadata) { this._addGeometryMetadata(dracoMesh, options.metadata); } const attributes = this._getAttributesFromMesh(mesh); this._createDracoMesh(dracoMesh, attributes, options); const dracoData = new this.draco.DracoInt8Array(); try { const encodedLen = this.dracoEncoder.EncodeMeshToDracoBuffer(dracoMesh, dracoData); if (encodedLen <= 0) { throw new Error("Draco encoding failed."); } this.log(`DRACO encoded ${dracoMesh.num_points()} points with ${dracoMesh.num_attributes()} attributes into ${encodedLen} bytes`); return dracoInt8ArrayToArrayBuffer(dracoData); } finally { this.destroyEncodedObject(dracoData); this.destroyEncodedObject(dracoMesh); } } /** * Set encoding options. * @param {{speed?: any; method?: any; quantization?: any;}} options */ _setOptions(options) { if ("speed" in options) { this.dracoEncoder.SetSpeedOptions(...options.speed); } if ("method" in options) { const dracoMethod = this.draco[options.method || "MESH_SEQUENTIAL_ENCODING"]; this.dracoEncoder.SetEncodingMethod(dracoMethod); } if ("quantization" in options) { for (const attribute in options.quantization) { const bits = options.quantization[attribute]; const dracoPosition = this.draco[attribute]; this.dracoEncoder.SetAttributeQuantization(dracoPosition, bits); } } } /** * @param {Mesh} dracoMesh * @param {object} attributes * @returns {Mesh} */ _createDracoMesh(dracoMesh, attributes, options) { const optionalMetadata = options.attributesMetadata || {}; try { const positions = this._getPositionAttribute(attributes); if (!positions) { throw new Error("positions"); } const vertexCount = positions.length / 3; for (let attributeName in attributes) { const attribute = attributes[attributeName]; attributeName = GLTF_TO_DRACO_ATTRIBUTE_NAME_MAP[attributeName] || attributeName; const uniqueId = this._addAttributeToMesh(dracoMesh, attributeName, attribute, vertexCount); if (uniqueId !== -1) { this._addAttributeMetadata(dracoMesh, uniqueId, { name: attributeName, ...optionalMetadata[attributeName] || {} }); } } } catch (error) { this.destroyEncodedObject(dracoMesh); throw error; } return dracoMesh; } /** * @param {} dracoPointCloud * @param {object} attributes */ _createDracoPointCloud(dracoPointCloud, attributes, options) { const optionalMetadata = options.attributesMetadata || {}; try { const positions = this._getPositionAttribute(attributes); if (!positions) { throw new Error("positions"); } const vertexCount = positions.length / 3; for (let attributeName in attributes) { const attribute = attributes[attributeName]; attributeName = GLTF_TO_DRACO_ATTRIBUTE_NAME_MAP[attributeName] || attributeName; const uniqueId = this._addAttributeToMesh( dracoPointCloud, attributeName, attribute, vertexCount ); if (uniqueId !== -1) { this._addAttributeMetadata(dracoPointCloud, uniqueId, { name: attributeName, ...optionalMetadata[attributeName] || {} }); } } } catch (error) { this.destroyEncodedObject(dracoPointCloud); throw error; } return dracoPointCloud; } /** * @param mesh * @param attributeName * @param attribute * @param vertexCount */ _addAttributeToMesh(mesh, attributeName, attribute, vertexCount) { if (!ArrayBuffer.isView(attribute)) { return -1; } const type = this._getDracoAttributeType(attributeName); const size = attribute.length / vertexCount; if (type === "indices") { const numFaces = attribute.length / 3; this.log(`Adding attribute ${attributeName}, size ${numFaces}`); this.dracoMeshBuilder.AddFacesToMesh(mesh, numFaces, attribute); return -1; } this.log(`Adding attribute ${attributeName}, size ${size}`); const builder = this.dracoMeshBuilder; const { buffer } = attribute; switch (attribute.constructor) { case Int8Array: return builder.AddInt8Attribute(mesh, type, vertexCount, size, new Int8Array(buffer)); case Int16Array: return builder.AddInt16Attribute(mesh, type, vertexCount, size, new Int16Array(buffer)); case Int32Array: return builder.AddInt32Attribute(mesh, type, vertexCount, size, new Int32Array(buffer)); case Uint8Array: case Uint8ClampedArray: return builder.AddUInt8Attribute(mesh, type, vertexCount, size, new Uint8Array(buffer)); case Uint16Array: return builder.AddUInt16Attribute(mesh, type, vertexCount, size, new Uint16Array(buffer)); case Uint32Array: return builder.AddUInt32Attribute(mesh, type, vertexCount, size, new Uint32Array(buffer)); case Float32Array: return builder.AddFloatAttribute(mesh, type, vertexCount, size, new Float32Array(buffer)); default: console.warn("Unsupported attribute type", attribute); return -1; } } /** * DRACO can compress attributes of know type better * TODO - expose an attribute type map? * @param attributeName */ _getDracoAttributeType(attributeName) { switch (attributeName.toLowerCase()) { case "indices": return "indices"; case "position": case "positions": case "vertices": return this.draco.POSITION; case "normal": case "normals": return this.draco.NORMAL; case "color": case "colors": return this.draco.COLOR; case "texcoord": case "texcoords": return this.draco.TEX_COORD; default: return this.draco.GENERIC; } } _getPositionAttribute(attributes) { for (const attributeName in attributes) { const attribute = attributes[attributeName]; const dracoType = this._getDracoAttributeType(attributeName); if (dracoType === this.draco.POSITION) { return attribute; } } return null; } /** * Add metadata for the geometry. * @param dracoGeometry - WASM Draco Object * @param metadata */ _addGeometryMetadata(dracoGeometry, metadata) { const dracoMetadata = new this.draco.Metadata(); this._populateDracoMetadata(dracoMetadata, metadata); this.dracoMeshBuilder.AddMetadata(dracoGeometry, dracoMetadata); } /** * Add metadata for an attribute to geometry. * @param dracoGeometry - WASM Draco Object * @param uniqueAttributeId * @param metadata */ _addAttributeMetadata(dracoGeometry, uniqueAttributeId, metadata) { const dracoAttributeMetadata = new this.draco.Metadata(); this._populateDracoMetadata(dracoAttributeMetadata, metadata); this.dracoMeshBuilder.SetMetadataForAttribute( dracoGeometry, uniqueAttributeId, dracoAttributeMetadata ); } /** * Add contents of object or map to a WASM Draco Metadata Object * @param dracoMetadata - WASM Draco Object * @param metadata */ _populateDracoMetadata(dracoMetadata, metadata) { for (const [key, value] of getEntries(metadata)) { switch (typeof value) { case "number": if (Math.trunc(value) === value) { this.dracoMetadataBuilder.AddIntEntry(dracoMetadata, key, value); } else { this.dracoMetadataBuilder.AddDoubleEntry(dracoMetadata, key, value); } break; case "object": if (value instanceof Int32Array) { this.dracoMetadataBuilder.AddIntEntryArray(dracoMetadata, key, value, value.length); } break; case "string": default: this.dracoMetadataBuilder.AddStringEntry(dracoMetadata, key, value); } } } }; function dracoInt8ArrayToArrayBuffer(dracoData) { const byteLength = dracoData.size(); const outputBuffer = new ArrayBuffer(byteLength); const outputData = new Int8Array(outputBuffer); for (let i = 0; i < byteLength; ++i) { outputData[i] = dracoData.GetValue(i); } return outputBuffer; } function getEntries(container) { const hasEntriesFunc = container.entries && !container.hasOwnProperty("entries"); return hasEntriesFunc ? container.entries() : Object.entries(container); } // src/lib/utils/version.ts var VERSION2 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest"; // src/draco-writer.ts var DEFAULT_DRACO_WRITER_OPTIONS = { pointcloud: false, // Set to true if pointcloud (mode: 0, no indices) attributeNameEntry: "name" // Draco Compression Parameters // method: 'MESH_EDGEBREAKER_ENCODING', // Use draco defaults // speed: [5, 5], // Use draco defaults // quantization: { // Use draco defaults // POSITION: 10 // } }; var DracoWriterWorker = { id: "draco-writer", name: "Draco compressed geometry writer", module: "draco", version: VERSION2, worker: true, options: { draco: {}, source: null } }; var DracoWriter = { name: "DRACO", id: "draco", module: "draco", version: VERSION2, extensions: ["drc"], mimeTypes: ["application/octet-stream"], options: { draco: DEFAULT_DRACO_WRITER_OPTIONS }, encode }; async function encode(data, options = {}) { const { draco } = await loadDracoEncoderModule(extractLoadLibraryOptions(options)); const dracoBuilder = new DracoBuilder(draco); try { return dracoBuilder.encodeSync(data, options.draco); } finally { dracoBuilder.destroy(); } } // ../schema-utils/src/lib/schema/data-type.ts function getDataTypeFromValue(value, defaultNumberType = "float32") { if (value instanceof Date) { return "date-millisecond"; } if (value instanceof Number) { return defaultNumberType; } if (typeof value === "string") { return "utf8"; } if (value === null || value === "undefined") { return "null"; } return "null"; } function getDataTypeFromArray(array) { let type = getDataTypeFromTypedArray(array); if (type !== "null") { return { type, nullable: false }; } if (array.length > 0) { type = getDataTypeFromValue(array[0]); return { type, nullable: true }; } return { type: "null", nullable: true }; } function getDataTypeFromTypedArray(array) { switch (array.constructor) { case Int8Array: return "int8"; case Uint8Array: case Uint8ClampedArray: return "uint8"; case Int16Array: return "int16"; case Uint16Array: return "uint16"; case Int32Array: return "int32"; case Uint32Array: return "uint32"; case Float32Array: return "float32"; case Float64Array: return "float64"; default: return "null"; } } // ../../node_modules/tslib/tslib.es6.mjs function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function(resolve) { resolve(value); }); } return new (P || (P = Promise))(function(resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __values(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function() { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __await(v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } function __asyncGenerator(thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function() { return this; }, i; function awaitReturn(f) { return function(v) { return Promise.resolve(v).then(f, reject); }; } function verb(n, f) { if (g[n]) { i[n] = function(v) { return new Promise(function(a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } } function __asyncDelegator(o) { var i, p; return i = {}, verb("next"), verb("throw", function(e) { throw e; }), verb("return"), i[Symbol.iterator] = function() { return this; }, i; function verb(n, f) { i[n] = o[n] ? function(v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; } } function __asyncValues(o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { return this; }, i); function verb(n) { i[n] = o[n] && function(v) { return new Promise(function(resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v2) { resolve({ value: v2, done: d }); }, reject); } } // ../../node_modules/apache-arrow/util/buffer.mjs var buffer_exports = {}; __export(buffer_exports, { compareArrayLike: () => compareArrayLike, joinUint8Arrays: () => joinUint8Arrays, memcpy: () => memcpy, rebaseValueOffsets: () => rebaseValueOffsets, toArrayBufferView: () => toArrayBufferView, toArrayBufferViewAsyncIterator: () => toArrayBufferViewAsyncIterator, toArrayBufferViewIterator: () => toArrayBufferViewIterator, toBigInt64Array: () => toBigInt64Array, toBigUint64Array: () => toBigUint64Array, toFloat32Array: () => toFloat32Array, toFloat32ArrayAsyncIterator: () => toFloat32ArrayAsyncIterator, toFloat32ArrayIterator: () => toFloat32ArrayIterator, toFloat64Array: () => toFloat64Array, toFloat64ArrayAsyncIterator: () => toFloat64ArrayAsyncIterator, toFloat64ArrayIterator: () => toFloat64ArrayIterator, toInt16Array: () => toInt16Array, toInt16ArrayAsyncIterator: () => toInt16ArrayAsyncIterator, toInt16ArrayIterator: () => toInt16ArrayIterator, toInt32Array: () => toInt32Array, toInt32ArrayAsyncIterator: () => toInt32ArrayAsyncIterator, toInt32ArrayIterator: () => toInt32ArrayIterator, toInt8Array: () => toInt8Array, toInt8ArrayAsyncIterator: () => toInt8ArrayAsyncIterator, toInt8ArrayIterator: () => toInt8ArrayIterator, toUint16Array: () => toUint16Array, toUint16ArrayAsyncIterator: () => toUint16ArrayAsyncIterator, toUint16ArrayIterator: () => toUint16ArrayIterator, toUint32Array: () => toUint32Array, toUint32ArrayAsyncIterator: () => toUint32ArrayAsyncIterator, toUint32ArrayIterator: () => toUint32ArrayIterator, toUint8Array: () => toUint8Array, toUint8ArrayAsyncIterator: () => toUint8ArrayAsyncIterator, toUint8ArrayIterator: () => toUint8ArrayIterator, toUint8ClampedArray: () => toUint8ClampedArray, toUint8ClampedArrayAsyncIterator: () => toUint8ClampedArrayAsyncIterator, toUint8ClampedArrayIterator: () => toUint8ClampedArrayIterator }); // ../../node_modules/apache-arrow/util/utf8.mjs var decoder = new TextDecoder("utf-8"); var decodeUtf8 = decoder.decode.bind(decoder); var encoder = new TextEncoder(); var encodeUtf8 = (value) => encoder.encode(value); // ../../node_modules/apache-arrow/util/compat.mjs var isNumber = (x) => typeof x === "number"; var isBoolean = (x) => typeof x === "boolean"; var isFunction = (x) => typeof x === "function"; var isObject = (x) => x != null && Object(x) === x; var isPromise = (x) => { return isObject(x) && isFunction(x.then); }; var isIterable = (x) => { return isObject(x) && isFunction(x[Symbol.iterator]); }; var isAsyncIterable = (x) => { return isObject(x) && isFunction(x[Symbol.asyncIterator]); }; var isArrowJSON = (x) => { return isObject(x) && isObject(x["schema"]); }; var isIteratorResult = (x) => { return isObject(x) && "done" in x && "value" in x; }; var isFileHandle = (x) => { return isObject(x) && isFunction(x["stat"]) && isNumber(x["fd"]); }; var isFetchResponse = (x) => { return isObject(x) && isReadableDOMStream(x["body"]); }; var isReadableInterop = (x) => "_getDOMStream" in x && "_getNodeStream" in x; var isWritableDOMStream = (x) => { return isObject(x) && isFunction(x["abort"]) && isFunction(x["getWriter"]) && !isReadableInterop(x); }; var isReadableDOMStream = (x) => { return isObject(x) && isFunction(x["cancel"]) && isFunction(x["getReader"]) && !isReadableInterop(x); }; var isWritableNodeStream = (x) => { return isObject(x) && isFunction(x["end"]) && isFunction(x["write"]) && isBoolean(x["writable"]) && !isReadableInterop(x); }; var isReadableNodeStream = (x) => { return isObject(x) && isFunction(x["read"]) && isFunction(x["pipe"]) && isBoolean(x["readable"]) && !isReadableInterop(x); }; var isFlatbuffersByteBuffer = (x) => { return isObject(x) && isFunction(x["clear"]) && isFunction(x["bytes"]) && isFunction(x["position"]) && isFunction(x["setPosition"]) && isFunction(x["capacity"]) && isFunction(x["getBufferIdentifier"]) && isFunction(x["createLong"]); }; // ../../node_modules/apache-arrow/util/buffer.mjs var SharedArrayBuf = typeof SharedArrayBuffer !== "undefined" ? SharedArrayBuffer : ArrayBuffer; function collapseContiguousByteRanges(chunks) { const result = chunks[0] ? [chunks[0]] : []; let xOffset, yOffset, xLen, yLen; for (let x, y, i = 0, j = 0, n = chunks.length; ++i < n; ) { x = result[j]; y = chunks[i]; if (!x || !y || x.buffer !== y.buffer || y.byteOffset < x.byteOffset) { y && (result[++j] = y); continue; } ({ byteOffset: xOffset, byteLength: xLen } = x); ({ byteOffset: yOffset, byteLength: yLen } = y); if (xOffset + xLen < yOffset || yOffset + yLen < xOffset) { y && (result[++j] = y); continue; } result[j] = new Uint8Array(x.buffer, xOffset, yOffset - xOffset + yLen); } return result; } function memcpy(target, source, targetByteOffset = 0, sourceByteLength = source.byteLength) { const targetByteLength = target.byteLength; const dst = new Uint8Array(target.buffer, target.byteOffset, targetByteLength); const src = new Uint8Array(source.buffer, source.byteOffset, Math.min(sourceByteLength, targetByteLength)); dst.set(src, targetByteOffset); return target; } function joinUint8Arrays(chunks, size) { const result = collapseContiguousByteRanges(chunks); const byteLength = result.reduce((x, b) => x + b.byteLength, 0); let source, sliced, buffer; let offset = 0, index = -1; const length = Math.min(size || Number.POSITIVE_INFINITY, byteLength); for (const n = result.length; ++index < n; ) { source = result[index]; sliced = source.subarray(0, Math.min(source.length, length - offset)); if (length <= offset + sliced.length) { if (sliced.length < source.length) { result[index] = source.subarray(sliced.length); } else if (sliced.length === source.length) { index++; } buffer ? memcpy(buffer, sliced, offset) : buffer = sliced; break; } memcpy(buffer || (buffer = new Uint8Array(length)), sliced, offset); offset += sliced.length; } return [buffer || new Uint8Array(0), result.slice(index), byteLength - (buffer ? buffer.byteLength : 0)]; } function toArrayBufferView(ArrayBufferViewCtor, input) { let value = isIteratorResult(input) ? input.value : input; if (value instanceof ArrayBufferViewCtor) { if (ArrayBufferViewCtor === Uint8Array) { return new ArrayBufferViewCtor(value.buffer, value.byteOffset, value.byteLength); } return value; } if (!value) { return new ArrayBufferViewCtor(0); } if (typeof value === "string") { value = encodeUtf8(value); } if (value instanceof ArrayBuffer) { return new ArrayBufferViewCtor(value); } if (value instanceof SharedArrayBuf) { return new ArrayBufferViewCtor(value); } if (isFlatbuffersByteBuffer(value)) { return toArrayBufferView(ArrayBufferViewCtor, value.bytes()); } return !ArrayBuffer.isView(value) ? ArrayBufferViewCtor.from(value) : value.byteLength <= 0 ? new ArrayBufferViewCtor(0) : new ArrayBufferViewCtor(value.buffer, value.byteOffset, value.byteLength / ArrayBufferViewCtor.BYTES_PER_ELEMENT); } var toInt8Array = (input) => toArrayBufferView(Int8Array, input); var toInt16Array = (input) => toArrayBufferView(Int16Array, input); var toInt32Array = (input) => toArrayBufferView(Int32Array, input); var toBigInt64Array = (input) => toArrayBufferView(BigInt64Array, input); var toUint8Array = (input) => toArrayBufferView(Uint8Array, input); var toUint16Array = (input) => toArrayBufferView(Uint16Array, input); var toUint32Array = (input) => toArrayBufferView(Uint32Array, input); var toBigUint64Array = (input) => toArrayBufferView(BigUint64Array, input); var toFloat32Array = (input) => toArrayBufferView(Float32Array, input); var toFloat64Array = (input) => toArrayBufferView(Float64Array, input); var toUint8ClampedArray = (input) => toArrayBufferView(Uint8ClampedArray, input); var pump = (iterator) => { iterator.next(); return iterator; }; function* toArrayBufferViewIterator(ArrayCtor, source) { const wrap = function* (x) { yield x; }; const buffers = typeof source === "string" ? wrap(source) : ArrayBuffer.isView(source) ? wrap(source) : source instanceof ArrayBuffer ? wrap(source) : source instanceof SharedArrayBuf ? wrap(source) : !isIterable(source) ? wrap(source) : source; yield* pump(function* (it) { let r = null; do { r = it.next(yield toArrayBufferView(ArrayCtor, r)); } while (!r.done); }(buffers[Symbol.iterator]())); return new ArrayCtor(); } var toInt8ArrayIterator = (input) => toArrayBufferViewIterator(Int8Array, input); var toInt16ArrayIterator = (input) => toArrayBufferViewIterator(Int16Array, input); var toInt32ArrayIterator = (input) => toArrayBufferViewIterator(Int32Array, input); var toUint8ArrayIterator = (input) => toArrayBufferViewIterator(Uint8Array, input); var toUint16ArrayIterator = (input) => toArrayBufferViewIterator(Uint16Array, input); var toUint32ArrayIterator = (input) => toArrayBufferViewIterator(Uint32Array, input); var toFloat32ArrayIterator = (input) => toArrayBufferViewIterator(Float32Array, input); var toFloat64ArrayIterator = (input) => toArrayBufferViewIterator(Float64Array, input); var toUint8ClampedArrayIterator = (input) => toArrayBufferViewIterator(Uint8ClampedArray, input); function toArrayBufferViewAsyncIterator(ArrayCtor, source) { return __asyncGenerator(this, arguments, function* toArrayBufferViewAsyncIterator_1() { if (isPromise(source)) { return yield __await(yield __await(yield* __asyncDelegator(__asyncValues(toArrayBufferViewAsyncIterator(ArrayCtor, yield __await(source)))))); } const wrap = function(x) { return __asyncGenerator(this, arguments, function* () { yield yield __await(yield __await(x)); }); }; const emit = function(source2) { return __asyncGenerator(this, arguments, function* () { yield __await(yield* __asyncDelegator(__asyncValues(pump(function* (it) { let r = null; do { r = it.next(yield r === null || r === void 0 ? void 0 : r.value); } while (!r.done); }(source2[Symbol.iterator]()))))); }); }; const buffers = typeof source === "string" ? wrap(source) : ArrayBuffer.isView(source) ? wrap(source) : source instanceof ArrayBuffer ? wrap(source) : source instanceof SharedArrayBuf ? wrap(source) : isIterable(source) ? emit(source) : !isAsyncIterable(source) ? wrap(source) : source; yield __await( // otherwise if AsyncIterable, use it yield* __asyncDelegator(__asyncValues(pump(function(it) { return __asyncGenerator(this, arguments, function* () { let r = null; do { r = yield __await(it.next(yield yield __await(toArrayBufferView(ArrayCtor, r)))); } while (!r.done); }); }(buffers[Symbol.asyncIterator]())))) ); return yield __await(new ArrayCtor()); }); } var toInt8ArrayAsyncIterator = (input) => toArrayBufferViewAsyncIterator(Int8Array, input); var toInt16ArrayAsyncIterator = (input) => toArrayBufferViewAsyncIterator(Int16Array, input); var toInt32ArrayAsyncIterator = (input) => toArrayBufferViewAsyncIterator(Int32Array, input); var toUint8ArrayAsyncIterator = (input) => toArrayBufferViewAsyncIterator(Uint8Array, input); var toUint16ArrayAsyncIterator = (input) => toArrayBufferViewAsyncIterator(Uint16Array, input); var toUint32ArrayAsyncIterator = (input) => toArrayBufferViewAsyncIterator(Uint32Array, input); var toFloat32ArrayAsyncIterator = (input) => toArrayBufferViewAsyncIterator(Float32Array, input); var toFloat64ArrayAsyncIterator = (input) => toArrayBufferViewAsyncIterator(Float64Array, input); var toUint8ClampedArrayAsyncIterator = (input) => toArrayBufferViewAsyncIterator(Uint8ClampedArray, input); function rebaseValueOffsets(offset, length, valueOffsets) { if (offset !== 0) { valueOffsets = valueOffsets.slice(0, length); for (let i = -1, n = valueOffsets.length; ++i < n; ) { valueOffsets[i] += offset; } } return valueOffsets.subarray(0, length); } function compareArrayLike(a, b) { let i = 0; const n = a.length; if (n !== b.length) { return false; } if (n > 0) { do { if (a[i] !== b[i]) { return false; } } while (++i < n); } return true; } // ../../node_modules/apache-arrow/io/adapters.mjs var adapters_default = { fromIterable(source) { return pump2(fromIterable(source)); }, fromAsyncIterable(source) { return pump2(fromAsyncIterable(source)); }, fromDOMStream(source) { return pump2(fromDOMStream(source)); }, fromNodeStream(stream) { return pump2(fromNodeStream(stream)); }, // @ts-ignore toDOMStream(source, options) { throw new Error(`"toDOMStream" not available in this environment`); }, // @ts-ignore toNodeStream(source, options) { throw new Error(`"toNodeStream" not available in this environment`); } }; var pump2 = (iterator) => { iterator.next(); return iterator; }; function* fromIterable(source) { let done, threw = false; let buffers = [], buffer; let cmd, size, bufferLength = 0; function byteRange() { if (cmd === "peek") { return joinUint8Arrays(buffers, size)[0]; } [buffer, buffers, bufferLength] = joinUint8Arrays(buffers, size); return buffer; } ({ cmd, size } = (yield (() => null)()) || { cmd: "read", size: 0 }); const it = toUint8ArrayIterator(source)[Symbol.iterator](); try { do { ({ done, value: buffer } = Number.isNaN(size - bufferLength) ? it.next() : it.next(size - bufferLength)); if (!done && buffer.byteLength > 0) { buffers.push(buffer); bufferLength += buffer.byteLength; } if (done || size <= bufferLength) { do { ({ cmd, size } = yield byteRange()); } while (size < bufferLength); } } while (!done); } catch (e) { threw = true; typeof it.throw === "function" && it.throw(e); } finally { threw === false && typeof it.return === "function" && it.return(null); } return null; } function fromAsyncIterable(source) { return __asyncGenerator(this, arguments, function* fromAsyncIterable_1() { let done, threw = false; let buffers = [], buffer; let cmd, size, bufferLength = 0; function byteRange() { if (cmd === "peek") { return joinUint8Arrays(buffers, size)[0]; } [buffer, buffers, bufferLength] = joinUint8Arrays(buffers, size); return buffer; } ({ cmd, size } = (yield yield __await((() => null)())) || { cmd: "read", size: 0 }); const it = toUint8ArrayAsyncIterator(source)[Symbol.asyncIterator](); try { do { ({ done, value: buffer } = Number.isNaN(size - bufferLength) ? yield __await(it.next()) : yield __await(it.next(size - bufferLength))); if (!done && buffer.byteLength > 0) { buffers.push(buffer); bufferLength += buffer.byteLength; } if (done || size <= bufferLength) { do { ({ cmd, size } = yield yield __await(byteRange())); } while (size < bufferLength); } } while (!done); } catch (e) { threw = true; typeof it.throw === "function" && (yield __await(it.throw(e))); } finally { threw === false && typeof it.return === "function" && (yield __await(it.return(new Uint8Array(0)))); } return yield __await(null); }); } function fromDOMStream(source) { return __asyncGenerator(this, arguments, fun