UNPKG

@softrobot/loaders.gl-draco

Version:

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

101 lines (84 loc) 3.42 kB
// Dynamic DRACO module loading inspired by THREE.DRACOLoader // https://github.com/mrdoob/three.js/blob/398c4f39ebdb8b23eefd4a7a5ec49ec0c96c7462/examples/jsm/loaders/DRACOLoader.js // by Don McCurdy / https://www.donmccurdy.com / MIT license import {loadLibrary, global} from '@loaders.gl/worker-utils'; const DRACO_VERSION = '1.4.1'; const DRACO_JS_DECODER_URL = `https://www.gstatic.com/draco/versioned/decoders/${DRACO_VERSION}/draco_decoder.js`; const DRACO_WASM_WRAPPER_URL = `https://www.gstatic.com/draco/versioned/decoders/${DRACO_VERSION}/draco_wasm_wrapper.js`; const DRACO_WASM_DECODER_URL = `https://www.gstatic.com/draco/versioned/decoders/${DRACO_VERSION}/draco_decoder.wasm`; const DRACO_ENCODER_URL = `https://raw.githubusercontent.com/google/draco/${DRACO_VERSION}/javascript/draco_encoder.js`; let loadDecoderPromise; let loadEncoderPromise; export async function loadDracoDecoderModule(options) { const modules = options.modules || {}; // Check if a bundled draco3d library has been supplied by application if (modules.draco3d) { loadDecoderPromise = loadDecoderPromise || modules.draco3d.createDecoderModule({}).then(draco => { return {draco}; }); } else { // If not, dynamically load the WASM script from our CDN loadDecoderPromise = loadDecoderPromise || loadDracoDecoder(options); } return await loadDecoderPromise; } export async function loadDracoEncoderModule(options) { const modules = options.modules || {}; // Check if a bundled draco3d library has been supplied by application if (modules.draco3d) { loadEncoderPromise = loadEncoderPromise || modules.draco3d.createEncoderModule({}).then(draco => { return {draco}; }); } else { // If not, dynamically load the WASM script from our CDN loadEncoderPromise = loadEncoderPromise || loadDracoEncoder(options); } return await loadEncoderPromise; } // DRACO DECODER LOADING async function loadDracoDecoder(options) { let DracoDecoderModule; let wasmBinary; switch (options.draco && options.draco.decoderType) { case 'js': DracoDecoderModule = await loadLibrary(DRACO_JS_DECODER_URL, 'draco', options); break; case 'wasm': default: [DracoDecoderModule, wasmBinary] = await Promise.all([ await loadLibrary(DRACO_WASM_WRAPPER_URL, 'draco', options), await loadLibrary(DRACO_WASM_DECODER_URL, 'draco', options) ]); } // Depends on how import happened... // @ts-ignore DracoDecoderModule = DracoDecoderModule || global.DracoDecoderModule; return await initializeDracoDecoder(DracoDecoderModule, wasmBinary); } function initializeDracoDecoder(DracoDecoderModule, wasmBinary) { 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. }); }); } // ENCODER async function loadDracoEncoder(options) { let DracoEncoderModule = await loadLibrary(DRACO_ENCODER_URL, 'draco', options); // @ts-ignore DracoEncoderModule = DracoEncoderModule || global.DracoEncoderModule; return new Promise(resolve => { DracoEncoderModule({ onModuleLoaded: draco => resolve({draco}) // Module is Promise-like. Wrap in object to avoid loop. }); }); }