/** * @author Don McCurdy / https://www.donmccurdy.com */ THREE.DRACOLoader = function ( manager ) { THREE.Loader.call( this, manager ); this.decoderType = typeof WebAssembly !== 'object' || this.workerLimit === 0 ? 'js' : 'wasm'; this.decoderConfig = {}; this.decoderBinary = null; this.decoderPending = null; this.workerLimit = 4; this.workerPool = []; this.workerNextTaskID = 1; this.workerSourceURL = ''; this.defaultAttributeIDs = { position: 'POSITION', normal: 'NORMAL', color: 'COLOR', uv: 'TEX_COORD' }; this.defaultAttributeTypes = { position: 'Float32Array', normal: 'Float32Array', color: 'Float32Array', uv: 'Float32Array' }; }; THREE.DRACOLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.DRACOLoader, setDecoderType: function ( type ) { this.decoderType = type; return this; }, setWorkerLimit: function ( workerLimit ) { this.workerLimit = workerLimit; return this; }, setVerbosity: function ( level ) { this.verbosity = level; return this; }, setDecoderConfig: function ( config ) { this.decoderConfig = config; return this; }, setDecoderPath: function ( path ) { this.decoderPath = path; return this; }, preload: function () { this._initDecoder(); return this; }, _initDecoder: function () { if ( this.decoderPending ) return this.decoderPending; const useJS = this.decoderType === 'js'; const librariesPending = []; if ( useJS ) { librariesPending.push( this._loadLibrary( 'draco_decoder.js', 'text' ) ); } else { librariesPending.push( this._loadLibrary( 'draco_wasm_wrapper.js', 'text' ) ); librariesPending.push( this._loadLibrary( 'draco_decoder.wasm', 'arraybuffer' ) ); } this.decoderPending = Promise.all( librariesPending ) .then( ( libraries ) => { const jsContent = libraries[ 0 ]; if ( useJS ) { this.decoderSourceURL = URL.createObjectURL( new Blob( [ jsContent ], { type: 'application/javascript' } ) ); } else { this.decoderSourceURL = URL.createObjectURL( new Blob( [ jsContent ], { type: 'application/javascript' } ) ); this.decoderConfig.wasmBinary = libraries[ 1 ]; } } ); return this.decoderPending; }, _loadLibrary: function ( url, responseType ) { const loader = new THREE.FileLoader( this.manager ); loader.setPath( this.decoderPath ); loader.setResponseType( responseType ); loader.setWithCredentials( this.withCredentials ); return new Promise( ( resolve, reject ) => { loader.load( url, resolve, undefined, reject ); } ); }, dispose: function () { this.workerPool.length = 0; if ( this.decoderSourceURL !== '' ) { URL.revokeObjectURL( this.decoderSourceURL ); } return this; } } );