| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| THREE.CTMLoader = function () { |
|
|
| }; |
|
|
| THREE.CTMLoader.prototype.constructor = THREE.CTMLoader; |
|
|
| |
|
|
| THREE.CTMLoader.prototype.loadParts = function ( url, callback, parameters ) { |
|
|
| parameters = parameters || {}; |
|
|
| var scope = this; |
|
|
| var xhr = new XMLHttpRequest(); |
|
|
| var basePath = parameters.basePath ? parameters.basePath : THREE.LoaderUtils.extractUrlBase( url ); |
|
|
| xhr.onreadystatechange = function () { |
|
|
| if ( xhr.readyState === 4 ) { |
|
|
| if ( xhr.status === 200 || xhr.status === 0 ) { |
|
|
| var jsonObject = JSON.parse( xhr.responseText ); |
|
|
| var materials = [], geometries = [], counter = 0; |
|
|
| function callbackFinal( geometry ) { |
|
|
| counter += 1; |
|
|
| geometries.push( geometry ); |
|
|
| if ( counter === jsonObject.offsets.length ) { |
|
|
| callback( geometries, materials ); |
|
|
| } |
|
|
| } |
|
|
|
|
| |
|
|
| for ( var i = 0; i < jsonObject.materials.length; i ++ ) { |
|
|
| materials[ i ] = THREE.Loader.prototype.createMaterial( jsonObject.materials[ i ], basePath ); |
|
|
| } |
|
|
| |
|
|
| var partUrl = basePath + jsonObject.data; |
| var parametersPart = { useWorker: parameters.useWorker, worker: parameters.worker, offsets: jsonObject.offsets }; |
| scope.load( partUrl, callbackFinal, parametersPart ); |
|
|
| } |
|
|
| } |
|
|
| }; |
|
|
| xhr.open( "GET", url, true ); |
| xhr.setRequestHeader( "Content-Type", "text/plain" ); |
| xhr.send( null ); |
|
|
| }; |
|
|
| |
| |
| |
| |
|
|
| THREE.CTMLoader.prototype.load = function ( url, callback, parameters ) { |
|
|
| parameters = parameters || {}; |
|
|
| var scope = this; |
|
|
| var offsets = parameters.offsets !== undefined ? parameters.offsets : [ 0 ]; |
|
|
| var xhr = new XMLHttpRequest(), |
| callbackProgress = null; |
|
|
| var length = 0; |
|
|
| xhr.onreadystatechange = function () { |
|
|
| if ( xhr.readyState === 4 ) { |
|
|
| if ( xhr.status === 200 || xhr.status === 0 ) { |
|
|
| var binaryData = new Uint8Array( xhr.response ); |
|
|
| var s = Date.now(); |
|
|
| if ( parameters.useWorker ) { |
|
|
| var worker = parameters.worker || new Worker( 'js/loaders/ctm/CTMWorker.js' ); |
|
|
| worker.onmessage = function ( event ) { |
|
|
| var files = event.data; |
|
|
| for ( var i = 0; i < files.length; i ++ ) { |
|
|
| var ctmFile = files[ i ]; |
|
|
| var e1 = Date.now(); |
| |
|
|
| scope.createModel( ctmFile, callback ); |
|
|
| var e = Date.now(); |
| console.log( "model load time [worker]: " + ( e - e1 ) + " ms, total: " + ( e - s ) ); |
|
|
| } |
|
|
|
|
| }; |
|
|
| worker.postMessage( { "data": binaryData, "offsets": offsets }, [ binaryData.buffer ] ); |
|
|
| } else { |
|
|
| for ( var i = 0; i < offsets.length; i ++ ) { |
|
|
| var stream = new CTM.Stream( binaryData ); |
| stream.offset = offsets[ i ]; |
|
|
| var ctmFile = new CTM.File( stream ); |
|
|
| scope.createModel( ctmFile, callback ); |
|
|
| } |
|
|
| |
| |
|
|
| } |
|
|
| } else { |
|
|
| console.error( "Couldn't load [" + url + "] [" + xhr.status + "]" ); |
|
|
| } |
|
|
| } else if ( xhr.readyState === 3 ) { |
|
|
| if ( callbackProgress ) { |
|
|
| if ( length === 0 ) { |
|
|
| length = xhr.getResponseHeader( "Content-Length" ); |
|
|
| } |
|
|
| callbackProgress( { total: length, loaded: xhr.responseText.length } ); |
|
|
| } |
|
|
| } else if ( xhr.readyState === 2 ) { |
|
|
| length = xhr.getResponseHeader( "Content-Length" ); |
|
|
| } |
|
|
| }; |
|
|
| xhr.open( "GET", url, true ); |
| xhr.responseType = "arraybuffer"; |
|
|
| xhr.send( null ); |
|
|
| }; |
|
|
|
|
| THREE.CTMLoader.prototype.createModel = function ( file, callback ) { |
|
|
| var Model = function () { |
|
|
| THREE.BufferGeometry.call( this ); |
|
|
| this.materials = []; |
|
|
| var indices = file.body.indices; |
| var positions = file.body.vertices; |
| var normals = file.body.normals; |
|
|
| var uvs, colors; |
|
|
| var uvMaps = file.body.uvMaps; |
|
|
| if ( uvMaps !== undefined && uvMaps.length > 0 ) { |
|
|
| uvs = uvMaps[ 0 ].uv; |
|
|
| } |
|
|
| var attrMaps = file.body.attrMaps; |
|
|
| if ( attrMaps !== undefined && attrMaps.length > 0 && attrMaps[ 0 ].name === 'Color' ) { |
|
|
| colors = attrMaps[ 0 ].attr; |
|
|
| } |
|
|
| this.setIndex( new THREE.BufferAttribute( indices, 1 ) ); |
| this.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); |
|
|
| if ( normals !== undefined ) { |
|
|
| this.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); |
|
|
| } |
|
|
| if ( uvs !== undefined ) { |
|
|
| this.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) ); |
|
|
| } |
|
|
| if ( colors !== undefined ) { |
|
|
| this.addAttribute( 'color', new THREE.BufferAttribute( colors, 4 ) ); |
|
|
| } |
|
|
| }; |
|
|
| Model.prototype = Object.create( THREE.BufferGeometry.prototype ); |
| Model.prototype.constructor = Model; |
|
|
| var geometry = new Model(); |
|
|
| |
| if ( geometry.attributes.normal === undefined ) { |
|
|
| geometry.computeVertexNormals(); |
|
|
| } |
|
|
| callback( geometry ); |
|
|
| }; |
|
|