three-loaders
Version:
This is a wrapper around threejs loaders to import it from any threejs application
81 lines • 10.9 kB
JavaScript
// Copyright 2016 The Draco Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
;function _typeof(a){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},_typeof(a)}var THREE=require("three"),DRACOLoader=function(a){// Native Draco attribute type to Three.JS attribute type.
this.timeLoaded=0,this.manager=a||THREE.DefaultLoadingManager,this.materials=null,this.verbosity=0,this.attributeOptions={},this.drawMode=THREE.TrianglesDrawMode,this.nativeAttributeMap={position:"POSITION",normal:"NORMAL",color:"COLOR",uv:"TEX_COORD"}};/**
* @param {THREE.LoadingManager} manager
*/ /**
* Sets the base path for decoder source files.
* @param {string} path
*/ /**
* Sets decoder configuration and releases singleton decoder module. Module
* will be recreated with the next decoding call.
* @param {Object} config
*/ /**
* Releases the singleton DracoDecoderModule instance. Module will be recreated
* with the next decoding call.
*/ /**
* Gets WebAssembly or asm.js singleton instance of DracoDecoderModule
* after testing for browser support. Returns Promise that resolves when
* module is available.
* @return {Promise<{decoder: DracoDecoderModule}>}
*/ /**
* @param {string} src
* @return {Promise}
*/ /**
* @param {string} src
* @return {Promise}
*/DRACOLoader.prototype={constructor:DRACOLoader,load:function g(a,b,c,d){var e=this,f=new THREE.FileLoader(e.manager);f.setPath(this.path),f.setResponseType("arraybuffer"),f.load(a,function(a){e.decodeDracoFile(a,b)},c,d)},setPath:function b(a){return this.path=a,this},setVerbosity:function b(a){return this.verbosity=a,this},/**
* Sets desired mode for generated geometry indices.
* Can be either:
* THREE.TrianglesDrawMode
* THREE.TriangleStripDrawMode
*/setDrawMode:function b(a){return this.drawMode=a,this},/**
* Skips dequantization for a specific attribute.
* |attributeName| is the THREE.js name of the given attribute type.
* The only currently supported |attributeName| is 'position', more may be
* added in future.
*/setSkipDequantization:function d(a,b){var c=!0;return"undefined"!=typeof b&&(c=b),this.getAttributeOptions(a).skipDequantization=c,this},/**
* Decompresses a Draco buffer. Names of attributes (for ID and type maps)
* must be one of the supported three.js types, including: position, color,
* normal, uv, uv2, skinIndex, skinWeight.
*
* @param {ArrayBuffer} rawBuffer
* @param {Function} callback
* @param {Object|undefined} attributeUniqueIdMap Provides a pre-defined ID
* for each attribute in the geometry to be decoded. If given,
* `attributeTypeMap` is required and `nativeAttributeMap` will be
* ignored.
* @param {Object|undefined} attributeTypeMap Provides a predefined data
* type (as a typed array constructor) for each attribute in the
* geometry to be decoded.
*/decodeDracoFile:function f(a,b,c,d){var e=this;DRACOLoader.getDecoderModule().then(function(f){e.decodeDracoFileInternal(a,f.decoder,b,c,d)})},decodeDracoFileInternal:function i(a,b,c,d,e){/*
* Here is how to use Draco Javascript decoder and get the geometry.
*/var f=new b.DecoderBuffer;f.Init(new Int8Array(a),a.byteLength);var g=new b.Decoder,h=g.GetEncodedGeometryType(f);/*
* Determine what type is this file: mesh or point cloud.
*/if(h==b.TRIANGULAR_MESH)0<this.verbosity&&console.log("Loaded a mesh.");else if(h==b.POINT_CLOUD)0<this.verbosity&&console.log("Loaded a point cloud.");else{throw console.error("THREE.DRACOLoader: Unknown geometry type."),new Error("THREE.DRACOLoader: Unknown geometry type.")}c(this.convertDracoGeometryTo3JS(b,g,h,f,d,e))},addAttributeToGeometry:function q(a,b,c,d,e,f,g,h){if(0===f.ptr){var j="THREE.DRACOLoader: No attribute "+d;throw console.error(j),new Error(j)}var k,l,m=f.num_components(),n=c.num_points(),o=n*m;switch(e){case Float32Array:k=new a.DracoFloat32Array,b.GetAttributeFloatForAllPoints(c,f,k),h[d]=new Float32Array(o),l=THREE.Float32BufferAttribute;break;case Int8Array:k=new a.DracoInt8Array,b.GetAttributeInt8ForAllPoints(c,f,k),h[d]=new Int8Array(o),l=THREE.Int8BufferAttribute;break;case Int16Array:k=new a.DracoInt16Array,b.GetAttributeInt16ForAllPoints(c,f,k),h[d]=new Int16Array(o),l=THREE.Int16BufferAttribute;break;case Int32Array:k=new a.DracoInt32Array,b.GetAttributeInt32ForAllPoints(c,f,k),h[d]=new Int32Array(o),l=THREE.Int32BufferAttribute;break;case Uint8Array:k=new a.DracoUInt8Array,b.GetAttributeUInt8ForAllPoints(c,f,k),h[d]=new Uint8Array(o),l=THREE.Uint8BufferAttribute;break;case Uint16Array:k=new a.DracoUInt16Array,b.GetAttributeUInt16ForAllPoints(c,f,k),h[d]=new Uint16Array(o),l=THREE.Uint16BufferAttribute;break;case Uint32Array:k=new a.DracoUInt32Array,b.GetAttributeUInt32ForAllPoints(c,f,k),h[d]=new Uint32Array(o),l=THREE.Uint32BufferAttribute;break;default:var j="THREE.DRACOLoader: Unexpected attribute type.";throw console.error(j),new Error(j);}// Copy data from decoder.
for(var p=0;p<o;p++)h[d][p]=k.GetValue(p);// Add attribute to THREEJS geometry for rendering.
g.addAttribute(d,new l(h[d],m)),a.destroy(k)},convertDracoGeometryTo3JS:function F(a,b,c,d,e,f){!0===this.getAttributeOptions("position").skipDequantization&&b.SkipAttributeTransform(a.POSITION);var g,h,j=performance.now();if(c===a.TRIANGULAR_MESH?(g=new a.Mesh,h=b.DecodeBufferToMesh(d,g)):(g=new a.PointCloud,h=b.DecodeBufferToPointCloud(d,g)),!h.ok()||0==g.ptr){var k="THREE.DRACOLoader: Decoding failed: ";throw k+=h.error_msg(),console.error(k),a.destroy(b),a.destroy(g),new Error(k)}var l=performance.now();a.destroy(d);/*
* Example on how to retrieve mesh and attributes.
*/var m;c==a.TRIANGULAR_MESH?(m=g.num_faces(),0<this.verbosity&&console.log("Number of faces loaded: "+m.toString())):m=0;var n=g.num_points(),o=g.num_attributes();0<this.verbosity&&(console.log("Number of points loaded: "+n.toString()),console.log("Number of attributes loaded: "+o.toString()));// Verify if there is position attribute.
// TODO: Should not assume native Draco attribute IDs apply.
var p=b.GetAttributeId(g,a.POSITION);if(-1==p){var k="THREE.DRACOLoader: No position attribute found.";throw console.error(k),a.destroy(b),a.destroy(g),new Error(k)}var q=b.GetAttribute(g,p),r={},s=new THREE.BufferGeometry;// Structure for converting to THREEJS geometry later.
// Do not use both the native attribute map and a provided (e.g. glTF) map.
if(e)// Add attributes of user specified unique id. E.g. GLTF models.
for(var t in e){var u=f[t],v=e[t],w=b.GetAttributeByUniqueId(g,v);this.addAttributeToGeometry(a,b,g,t,u,w,s,r)}else// Add native Draco attribute type to geometry.
for(var t in this.nativeAttributeMap){var x=b.GetAttributeId(g,a[this.nativeAttributeMap[t]]);if(-1!==x){0<this.verbosity&&console.log("Loaded "+t+" attribute.");var w=b.GetAttribute(g,x);this.addAttributeToGeometry(a,b,g,t,Float32Array,w,s,r)}}// For mesh, we need to generate the faces.
if(c==a.TRIANGULAR_MESH)if(this.drawMode===THREE.TriangleStripDrawMode){var y=new a.DracoInt32Array,z=b.GetTriangleStripsFromMesh(g,y);r.indices=new Uint32Array(y.size());for(var A=0;A<y.size();++A)r.indices[A]=y.GetValue(A);a.destroy(y)}else{var B=3*m;r.indices=new Uint32Array(B);for(var C=new a.DracoInt32Array,A=0;A<m;++A){b.GetFaceFromMesh(g,A,C);var D=3*A;r.indices[D]=C.GetValue(0),r.indices[D+1]=C.GetValue(1),r.indices[D+2]=C.GetValue(2)}a.destroy(C)}s.drawMode=this.drawMode,c==a.TRIANGULAR_MESH&&s.setIndex(new(65535<r.indices.length?THREE.Uint32BufferAttribute:THREE.Uint16BufferAttribute)(r.indices,1));// TODO: Should not assume native Draco attribute IDs apply.
// TODO: Can other attribute types be quantized?
var E=new a.AttributeQuantizationTransform;if(E.InitFromAttribute(q)){s.attributes.position.isQuantized=!0,s.attributes.position.maxRange=E.range(),s.attributes.position.numQuantizationBits=E.quantization_bits(),s.attributes.position.minValues=new Float32Array(3);for(var A=0;3>A;++A)s.attributes.position.minValues[A]=E.min_value(A)}return a.destroy(E),a.destroy(b),a.destroy(g),this.decode_time=l-j,this.import_time=performance.now()-l,0<this.verbosity&&(console.log("Decode time: "+this.decode_time),console.log("Import time: "+this.import_time)),s},isVersionSupported:function c(a,b){DRACOLoader.getDecoderModule().then(function(c){b(c.decoder.isVersionSupported(a))})},getAttributeOptions:function b(a){return"undefined"==typeof this.attributeOptions[a]&&(this.attributeOptions[a]={}),this.attributeOptions[a]}},DRACOLoader.decoderPath="./",DRACOLoader.decoderConfig={},DRACOLoader.decoderModulePromise=null,DRACOLoader.setDecoderPath=function(a){DRACOLoader.decoderPath=a},DRACOLoader.setDecoderConfig=function(a){var b=DRACOLoader.decoderConfig.wasmBinary;DRACOLoader.decoderConfig=a||{},DRACOLoader.releaseDecoderModule(),b&&(DRACOLoader.decoderConfig.wasmBinary=b)},DRACOLoader.releaseDecoderModule=function(){DRACOLoader.decoderModulePromise=null},DRACOLoader.getDecoderModule=function(){var a=this,b=DRACOLoader.decoderPath,c=DRACOLoader.decoderConfig,d=DRACOLoader.decoderModulePromise;return d?d:("undefined"==typeof DracoDecoderModule?"object"!==("undefined"==typeof WebAssembly?"undefined":_typeof(WebAssembly))||"js"===c.type?d=DRACOLoader._loadScript(b+"draco_decoder.js"):(c.wasmBinaryFile=b+"draco_decoder.wasm",d=DRACOLoader._loadScript(b+"draco_wasm_wrapper.js").then(function(){return DRACOLoader._loadArrayBuffer(c.wasmBinaryFile)}).then(function(a){c.wasmBinary=a})):d=Promise.resolve(),d=d.then(function(){return new Promise(function(b){c.onModuleLoaded=function(c){a.timeLoaded=performance.now(),b({decoder:c})},DracoDecoderModule(c)})}),DRACOLoader.decoderModulePromise=d,d);// Load source files.
},DRACOLoader._loadScript=function(a){var b=document.getElementById("decoder_script");null!==b&&b.parentNode.removeChild(b);var c=document.getElementsByTagName("head")[0],d=document.createElement("script");return d.id="decoder_script",d.type="text/javascript",d.src=a,new Promise(function(a){d.onload=a,c.appendChild(d)})},DRACOLoader._loadArrayBuffer=function(a){var b=new THREE.FileLoader;return b.setResponseType("arraybuffer"),new Promise(function(c,d){b.load(a,c,void 0,d)})},module.exports=exports.default=DRACOLoader;