mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
102.4k stars 35.35k forks source link

UTF8Loader onProgress #6350

Closed RemusMar closed 6 years ago

RemusMar commented 9 years ago

In my opinion this adapted Google webgl-loader is the best option for big (static) meshes. Compared to OBJ, JS and DAE it provides an awesome 1:6 ... 1:8 compression. Unfortunately, the onProgress callback is not implemented. Something like "onProgress = function( data )" with data.loaded and data.total would be great.

cheers

RemusMar commented 9 years ago

I didn't see many people interested in this subject. (probably because I didn't see any serious project made in THREE ...) Anyway, for those interested: Here is the updated UTF8 loader (with progress callback): http://necromanthus.com/Test/html5/JS/UTF8Loader.js

And here you can see it in action: http://necromanthus.com/Test/html5/test9.html

cheers

mrdoob commented 9 years ago

That's a lot of things that changed.

diff --git a/examples/js/loaders/UTF8Loader.js b/examples/js/loaders/UTF8Loader.js
index bca7d9a..b6eb004 100644
--- a/examples/js/loaders/UTF8Loader.js
+++ b/examples/js/loaders/UTF8Loader.js
@@ -1,781 +1,430 @@
-/**
- * Loader for UTF8 version2 (after r51) encoded models generated by:
- * http://code.google.com/p/webgl-loader/
- *
- * Code to load/decompress mesh is taken from r100 of this webgl-loader
- */
-
-THREE.UTF8Loader = function () {};
-
-/**
- * Load UTF8 encoded model
- * @param jsonUrl - URL from which to load json containing information about model
- * @param callback - Callback(THREE.Object3D) on successful loading of model
- * @param options - options on how to load model (see THREE.MTLLoader.MaterialCreator for basic options)
- *                  Additional options include
- *                   geometryBase: Base url from which to load referenced geometries
- *                   materialBase: Base url from which to load referenced textures
- */
-
-THREE.UTF8Loader.prototype.load = function ( jsonUrl, callback, options ) {
-
-   this.downloadModelJson( jsonUrl, callback, options );
-
+THREE.UTF8Loader = function ( showStatus ) {
+   THREE.Loader.call( this, showStatus );
 };

-// BufferGeometryCreator
+THREE.UTF8Loader.prototype.load = function ( jsonUrl, callback, options, callbackProgress ) {
+   this.downloadModelJson( jsonUrl, callback, options, callbackProgress );
+};

 THREE.UTF8Loader.BufferGeometryCreator = function () {
 };

 THREE.UTF8Loader.BufferGeometryCreator.prototype.create = function ( attribArray, indices ) {
-
    var ntris = indices.length / 3;
-
    var geometry = new THREE.BufferGeometry();
-
    var positions = new Float32Array( ntris * 3 * 3 );
    var normals = new Float32Array( ntris * 3 * 3 );
    var uvs = new Float32Array( ntris * 3 * 2 );
-
    var i, j, offset;
    var x, y, z;
    var u, v;
-
    var end = attribArray.length;
    var stride = 8;
-
-   // extract positions
-
    j = 0;
    offset = 0;
-
    for ( i = offset; i < end; i += stride ) {
-
        x = attribArray[ i ];
        y = attribArray[ i + 1 ];
        z = attribArray[ i + 2 ];
-
        positions[ j ++ ] = x;
        positions[ j ++ ] = y;
        positions[ j ++ ] = z;
-
    }
-
-   // extract uvs
-
    j = 0;
    offset = 3;
-
    for ( i = offset; i < end; i += stride ) {
-
        u = attribArray[ i ];
        v = attribArray[ i + 1 ];
-
        uvs[ j ++ ] = u;
        uvs[ j ++ ] = v;
-
    }
-
-   // extract normals
-
    j = 0;
    offset = 5;
-
    for ( i = offset; i < end; i += stride ) {
-
        x = attribArray[ i ];
        y = attribArray[ i + 1 ];
        z = attribArray[ i + 2 ];
-
        normals[ j ++ ] = x;
        normals[ j ++ ] = y;
        normals[ j ++ ] = z;
-
    }
-
    geometry.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) );
    geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
    geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
    geometry.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
-
    geometry.offsets.push( { start: 0, count: indices.length, index: 0 } );
-
    geometry.computeBoundingSphere();
-
    return geometry;
-
 };

-
-// UTF-8 decoder from webgl-loader (r100)
-// http://code.google.com/p/webgl-loader/
-
-// Model manifest description. Contains objects like:
-// name: {
-//   materials: { 'material_name': { ... } ... },
-//   decodeParams: {
-//     decodeOffsets: [ ... ],
-//     decodeScales: [ ... ],
-//   },
-//   urls: {
-//     'url': [
-//       { material: 'material_name',
-//         attribRange: [#, #],
-//         indexRange: [#, #],
-//         names: [ 'object names' ... ],
-//         lengths: [#, #, # ... ]
-//       }
-//     ],
-//     ...
-//   }
-// }
-
 var DEFAULT_DECODE_PARAMS = {
-
     decodeOffsets: [ -4095, -4095, -4095, 0, 0, -511, -511, -511 ],
     decodeScales: [ 1 / 8191, 1 / 8191, 1 / 8191, 1 / 1023, 1 / 1023, 1 / 1023, 1 / 1023, 1 / 1023 ]
-
-    // TODO: normal decoding? (see walt.js)
-    // needs to know: input, output (from vertex format!)
-    //
-    // Should split attrib/index.
-    // 1) Decode position and non-normal attributes.
-    // 2) Decode indices, computing normals
-    // 3) Maybe normalize normals? Only necessary for refinement, or fixed?
-    // 4) Maybe refine normals? Should this be part of regular refinement?
-    // 5) Morphing
-
 };

-// Triangle strips!
-
-// TODO: will it be an optimization to specialize this method at
-// runtime for different combinations of stride, decodeOffset and
-// decodeScale?
-
-THREE.UTF8Loader.prototype.decompressAttribsInner_ = function ( str, inputStart, inputEnd,
-                                                                  output, outputStart, stride,
-                                                                  decodeOffset, decodeScale ) {

+THREE.UTF8Loader.prototype.decompressAttribsInner_ = function ( str, inputStart, inputEnd, output, outputStart, stride, decodeOffset, decodeScale ) {
    var prev = 0;
-
    for ( var j = inputStart; j < inputEnd; j ++ ) {
-
        var code = str.charCodeAt( j );
        prev += ( code >> 1 ) ^ ( -( code & 1 ) );
-
        output[ outputStart ] = decodeScale * ( prev + decodeOffset );
        outputStart += stride;
-
    }
-
 };

-THREE.UTF8Loader.prototype.decompressIndices_ = function( str, inputStart, numIndices,
-                                                            output, outputStart ) {
-
+THREE.UTF8Loader.prototype.decompressIndices_ = function( str, inputStart, numIndices, output, outputStart ) {
    var highest = 0;
-
    for ( var i = 0; i < numIndices; i ++ ) {
-
        var code = str.charCodeAt( inputStart ++ );
-
        output[ outputStart ++ ] = highest - code;
-
        if ( code === 0 ) {
-
            highest ++;
-
        }
-
    }
-
 };

-THREE.UTF8Loader.prototype.decompressAABBs_ = function ( str, inputStart, numBBoxen,
-                                                           decodeOffsets, decodeScales ) {
+THREE.UTF8Loader.prototype.decompressAABBs_ = function ( str, inputStart, numBBoxen, decodeOffsets, decodeScales ) {
    var numFloats = 6 * numBBoxen;
-
    var inputEnd = inputStart + numFloats;
    var outputStart = 0;
-
    var bboxen = new Float32Array( numFloats );
-
    for ( var i = inputStart; i < inputEnd; i += 6 ) {
-
        var minX = str.charCodeAt(i + 0) + decodeOffsets[0];
        var minY = str.charCodeAt(i + 1) + decodeOffsets[1];
        var minZ = str.charCodeAt(i + 2) + decodeOffsets[2];
-
        var radiusX = (str.charCodeAt(i + 3) + 1) >> 1;
        var radiusY = (str.charCodeAt(i + 4) + 1) >> 1;
        var radiusZ = (str.charCodeAt(i + 5) + 1) >> 1;
-
        bboxen[ outputStart ++ ] = decodeScales[0] * (minX + radiusX);
        bboxen[ outputStart ++ ] = decodeScales[1] * (minY + radiusY);
        bboxen[ outputStart ++ ] = decodeScales[2] * (minZ + radiusZ);
-
        bboxen[ outputStart ++ ] = decodeScales[0] * radiusX;
        bboxen[ outputStart ++ ] = decodeScales[1] * radiusY;
        bboxen[ outputStart ++ ] = decodeScales[2] * radiusZ;
-
    }
-
    return bboxen;
-
 };

 THREE.UTF8Loader.prototype.decompressMesh =  function ( str, meshParams, decodeParams, name, idx, callback ) {
-
-    // Extract conversion parameters from attribArrays.
-
    var stride = decodeParams.decodeScales.length;
-
    var decodeOffsets = decodeParams.decodeOffsets;
    var decodeScales = decodeParams.decodeScales;
-
    var attribStart = meshParams.attribRange[0];
    var numVerts = meshParams.attribRange[1];
-
-    // Decode attributes.
-
    var inputOffset = attribStart;
    var attribsOut = new Float32Array( stride * numVerts );
-
    for (var j = 0; j < stride; j ++ ) {
-
        var end = inputOffset + numVerts;
-
        var decodeScale = decodeScales[j];
-
        if ( decodeScale ) {
-
-            // Assume if decodeScale is never set, simply ignore the
-            // attribute.
-
            this.decompressAttribsInner_( str, inputOffset, end,
                 attribsOut, j, stride,
                 decodeOffsets[j], decodeScale );
        }
-
        inputOffset = end;
-
    }
-
    var indexStart = meshParams.indexRange[ 0 ];
    var numIndices = 3 * meshParams.indexRange[ 1 ];
-
    var indicesOut = new Uint16Array( numIndices );
-
    this.decompressIndices_( str, inputOffset, numIndices, indicesOut, 0 );
-
-    // Decode bboxen.
-
    var bboxen = undefined;
    var bboxOffset = meshParams.bboxes;
-
    if ( bboxOffset ) {
-
        bboxen = this.decompressAABBs_( str, bboxOffset, meshParams.names.length, decodeOffsets, decodeScales );
    }
-
    callback( name, idx, attribsOut, indicesOut, bboxen, meshParams );
-
 };

 THREE.UTF8Loader.prototype.copyAttrib = function ( stride, attribsOutFixed, lastAttrib, index ) {
-
    for ( var j = 0; j < stride; j ++ ) {
-
        lastAttrib[ j ] = attribsOutFixed[ stride * index + j ];
-
    }
-
 };

 THREE.UTF8Loader.prototype.decodeAttrib2 = function ( str, stride, decodeOffsets, decodeScales, deltaStart,
-                                                        numVerts, attribsOut, attribsOutFixed, lastAttrib,
-                                                        index ) {
-
+                                                        numVerts, attribsOut, attribsOutFixed, lastAttrib, index ) {
    for ( var j = 0; j < 5; j ++ ) {
-
        var code = str.charCodeAt( deltaStart + numVerts * j + index );
        var delta = ( code >> 1) ^ (-(code & 1));
-
        lastAttrib[ j ] += delta;
        attribsOutFixed[ stride * index + j ] = lastAttrib[ j ];
        attribsOut[ stride * index + j ] = decodeScales[ j ] * ( lastAttrib[ j ] + decodeOffsets[ j ] );
    }
-
 };

 THREE.UTF8Loader.prototype.accumulateNormal = function ( i0, i1, i2, attribsOutFixed, crosses ) {
-
    var p0x = attribsOutFixed[ 8 * i0 ];
    var p0y = attribsOutFixed[ 8 * i0 + 1 ];
    var p0z = attribsOutFixed[ 8 * i0 + 2 ];
-
    var p1x = attribsOutFixed[ 8 * i1 ];
    var p1y = attribsOutFixed[ 8 * i1 + 1 ];
    var p1z = attribsOutFixed[ 8 * i1 + 2 ];
-
    var p2x = attribsOutFixed[ 8 * i2 ];
    var p2y = attribsOutFixed[ 8 * i2 + 1 ];
    var p2z = attribsOutFixed[ 8 * i2 + 2 ];
-
    p1x -= p0x;
    p1y -= p0y;
    p1z -= p0z;
-
    p2x -= p0x;
    p2y -= p0y;
    p2z -= p0z;
-
    p0x = p1y * p2z - p1z * p2y;
    p0y = p1z * p2x - p1x * p2z;
    p0z = p1x * p2y - p1y * p2x;
-
    crosses[ 3 * i0 ]     += p0x;
    crosses[ 3 * i0 + 1 ] += p0y;
    crosses[ 3 * i0 + 2 ] += p0z;
-
    crosses[ 3 * i1 ]     += p0x;
    crosses[ 3 * i1 + 1 ] += p0y;
    crosses[ 3 * i1 + 2 ] += p0z;
-
    crosses[ 3 * i2 ]     += p0x;
    crosses[ 3 * i2 + 1 ] += p0y;
    crosses[ 3 * i2 + 2 ] += p0z;
-
 };

 THREE.UTF8Loader.prototype.decompressMesh2 = function( str, meshParams, decodeParams, name, idx, callback ) {
-
    var MAX_BACKREF = 96;
-
-    // Extract conversion parameters from attribArrays.
-
    var stride = decodeParams.decodeScales.length;
-
    var decodeOffsets = decodeParams.decodeOffsets;
    var decodeScales = decodeParams.decodeScales;
-
    var deltaStart = meshParams.attribRange[ 0 ];
    var numVerts = meshParams.attribRange[ 1 ];
-
    var codeStart = meshParams.codeRange[ 0 ];
    var codeLength = meshParams.codeRange[ 1 ];
-
    var numIndices = 3 * meshParams.codeRange[ 2 ];
-
    var indicesOut = new Uint16Array( numIndices );
-
    var crosses = new Int32Array( 3 * numVerts );
-
    var lastAttrib = new Uint16Array( stride );
-
    var attribsOutFixed = new Uint16Array( stride * numVerts );
    var attribsOut = new Float32Array( stride * numVerts );
-
    var highest = 0;
    var outputStart = 0;
-
    for ( var i = 0; i < numIndices; i += 3 ) {
-
        var code = str.charCodeAt( codeStart ++ );
-
        var max_backref = Math.min( i, MAX_BACKREF );
-
        if ( code < max_backref ) {
-
-            // Parallelogram
-
            var winding = code % 3;
            var backref = i - ( code - winding );
            var i0, i1, i2;
-
            switch ( winding ) {
-
                case 0:
-
                    i0 = indicesOut[ backref + 2 ];
                    i1 = indicesOut[ backref + 1 ];
                    i2 = indicesOut[ backref + 0 ];
                    break;
-
                case 1:
-
                    i0 = indicesOut[ backref + 0 ];
                    i1 = indicesOut[ backref + 2 ];
                    i2 = indicesOut[ backref + 1 ];
                    break;
-
                case 2:
-
                    i0 = indicesOut[ backref + 1 ];
                    i1 = indicesOut[ backref + 0 ];
                    i2 = indicesOut[ backref + 2 ];
                    break;
-
            }
-
            indicesOut[ outputStart ++ ] = i0;
            indicesOut[ outputStart ++ ] = i1;
-
            code = str.charCodeAt( codeStart ++ );
-
            var index = highest - code;
            indicesOut[ outputStart ++ ] = index;
-
            if ( code === 0 ) {
-
                for (var j = 0; j < 5; j ++ ) {
-
                    var deltaCode = str.charCodeAt( deltaStart + numVerts * j + highest );
-
                    var prediction = ((deltaCode >> 1) ^ (-(deltaCode & 1))) +
-                        attribsOutFixed[stride * i0 + j] +
-                        attribsOutFixed[stride * i1 + j] -
-                        attribsOutFixed[stride * i2 + j];
-
+                        attribsOutFixed[stride * i0 + j] + attribsOutFixed[stride * i1 + j] - attribsOutFixed[stride * i2 + j];
                    lastAttrib[j] = prediction;
-
                    attribsOutFixed[ stride * highest + j ] = prediction;
                    attribsOut[ stride * highest + j ] = decodeScales[ j ] * ( prediction + decodeOffsets[ j ] );
-
                }
-
                highest ++;
-
            } else {
-
                this.copyAttrib( stride, attribsOutFixed, lastAttrib, index );
-
            }
-
            this.accumulateNormal( i0, i1, index, attribsOutFixed, crosses );
-
        } else {
-
-            // Simple
-
            var index0 = highest - ( code - max_backref );
-
            indicesOut[ outputStart ++ ] = index0;
-
            if ( code === max_backref ) {
-
-               this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
-                    numVerts, attribsOut, attribsOutFixed, lastAttrib,
-                    highest ++ );
-
+               this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart, numVerts, attribsOut, attribsOutFixed, lastAttrib, highest ++ );
            } else {
-
                this.copyAttrib(stride, attribsOutFixed, lastAttrib, index0);
-
            }
-
            code = str.charCodeAt( codeStart ++ );
-
            var index1 = highest - code;
            indicesOut[ outputStart ++ ] = index1;
-
            if ( code === 0 ) {
-
-               this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
-                    numVerts, attribsOut, attribsOutFixed, lastAttrib,
-                    highest ++ );
-
+               this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart, numVerts, attribsOut, attribsOutFixed, lastAttrib, highest ++ );
            } else {
-
                this.copyAttrib( stride, attribsOutFixed, lastAttrib, index1 );
-
            }
-
            code = str.charCodeAt( codeStart ++ );
-
            var index2 = highest - code;
            indicesOut[ outputStart ++ ] = index2;
-
            if ( code === 0 ) {
-
                for ( var j = 0; j < 5; j ++ ) {
-
                    lastAttrib[ j ] = ( attribsOutFixed[ stride * index0 + j ] + attribsOutFixed[ stride * index1 + j ] ) / 2;
-
                }
-
                this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
-                    numVerts, attribsOut, attribsOutFixed, lastAttrib,
-                    highest ++ );
-
+                    numVerts, attribsOut, attribsOutFixed, lastAttrib, highest ++ );
            } else {
-
                this.copyAttrib( stride, attribsOutFixed, lastAttrib, index2 );
-
            }
-
            this.accumulateNormal( index0, index1, index2, attribsOutFixed, crosses );
-
        }
-
    }
-
    for ( var i = 0; i < numVerts; i ++ ) {
-
        var nx = crosses[ 3 * i ];
        var ny = crosses[ 3 * i + 1 ];
        var nz = crosses[ 3 * i + 2 ];
-
        var norm = 511.0 / Math.sqrt( nx * nx + ny * ny + nz * nz );
-
        var cx = str.charCodeAt( deltaStart + 5 * numVerts + i );
        var cy = str.charCodeAt( deltaStart + 6 * numVerts + i );
        var cz = str.charCodeAt( deltaStart + 7 * numVerts + i );
-
        attribsOut[ stride * i + 5 ] = norm * nx + ((cx >> 1) ^ (-(cx & 1)));
        attribsOut[ stride * i + 6 ] = norm * ny + ((cy >> 1) ^ (-(cy & 1)));
        attribsOut[ stride * i + 7 ] = norm * nz + ((cz >> 1) ^ (-(cz & 1)));
    }
-
    callback( name, idx, attribsOut, indicesOut, undefined, meshParams );
-
 };

-THREE.UTF8Loader.prototype.downloadMesh = function ( path, name, meshEntry, decodeParams, callback ) {
-
+THREE.UTF8Loader.prototype.downloadMesh = function ( path, name, meshEntry, decodeParams, callback, callbackProgress ) {
    var loader = this;
    var idx = 0;
-
+   var xhr = new XMLHttpRequest();
+   var length = 0;
    function onprogress( req, e ) {
-
        while ( idx < meshEntry.length ) {
-
            var meshParams = meshEntry[ idx ];
            var indexRange = meshParams.indexRange;
-
            if ( indexRange ) {
-
                var meshEnd = indexRange[ 0 ] + 3 * indexRange[ 1 ];
-
                if ( req.responseText.length < meshEnd ) break;
-
                loader.decompressMesh( req.responseText, meshParams, decodeParams, name, idx, callback );
-
            } else {
-
                var codeRange = meshParams.codeRange;
                var meshEnd = codeRange[ 0 ] + codeRange[ 1 ];
-
                if ( req.responseText.length < meshEnd ) break;
-
                loader.decompressMesh2( req.responseText, meshParams, decodeParams, name, idx, callback );
            }
-
            ++ idx;
-
        }
-
-   }
-
-   getHttpRequest( path, function( req, e ) {
-
-       if ( req.status === 200 || req.status === 0 ) {
-
-           onprogress( req, e );
-
+   };
+   xhr.onreadystatechange = function( e ) {
+       if ( xhr.readyState == 4 ) {
+           if ( xhr.status == 200 || xhr.status == 0 ) {
+               onprogress( xhr, e );
+           }
+       } else if ( xhr.readyState == 3 ) {
+           if ( callbackProgress ) {
+               if ( length == 0 ) {
+                   length = xhr.getResponseHeader( "Content-Length" );
+               }
+               callbackProgress( {total: length, loaded: xhr.responseText.length} );
+           }
        }
-
-        // TODO: handle errors.
-
-   }, onprogress );
-
+   }
+   xhr.open( "GET", path, true );
+   xhr.send( null );
 };

-THREE.UTF8Loader.prototype.downloadMeshes = function ( path, meshUrlMap, decodeParams, callback ) {
-
+THREE.UTF8Loader.prototype.downloadMeshes = function ( path, meshUrlMap, decodeParams, callback, callbackProgress ) {
    for ( var url in meshUrlMap ) {
-
        var meshEntry = meshUrlMap[url];
-       this.downloadMesh( path + url, url, meshEntry, decodeParams, callback );
-
+       this.downloadMesh( path + url, url, meshEntry, decodeParams, callback, callbackProgress );
    }
-
 };

 THREE.UTF8Loader.prototype.createMeshCallback = function( materialBaseUrl, loadModelInfo, allDoneCallback ) {
-
    var nCompletedUrls = 0;
    var nExpectedUrls = 0;
-
    var expectedMeshesPerUrl = {};
    var decodedMeshesPerUrl = {};
-
    var modelParts = {};
-
    var meshUrlMap = loadModelInfo.urls;
-
    for ( var url in meshUrlMap ) {
-
        expectedMeshesPerUrl[ url ] = meshUrlMap[ url ].length;
        decodedMeshesPerUrl[ url ] = 0;
-
        nExpectedUrls ++;
-
        modelParts[ url ] = new THREE.Object3D();
-
    }
-
    var model = new THREE.Object3D();
-
-    // Prepare materials first...
-
    var materialCreator = new THREE.MTLLoader.MaterialCreator( materialBaseUrl, loadModelInfo.options );
    materialCreator.setMaterials( loadModelInfo.materials );
-
    materialCreator.preload();
-
-   // Create callback for creating mesh parts
-
    var bufferGeometryCreator = new THREE.UTF8Loader.BufferGeometryCreator();
-
    var meshCallback = function( name, idx, attribArray, indexArray, bboxen, meshParams ) {
-
-        // Got ourselves a new mesh
-
-        // name identifies this part of the model (url)
-        // idx is the mesh index of this mesh of the part
-        // attribArray defines the vertices
-        // indexArray defines the faces
-        // bboxen defines the bounding box
-        // meshParams contains the material info
-
        var geometry = bufferGeometryCreator.create( attribArray, indexArray );
        var material = materialCreator.create( meshParams.material );
-
        var mesh = new THREE.Mesh( geometry, material );
        modelParts[ name ].add( mesh );
-
         //model.add(new THREE.Mesh(geometry, material));
-
        decodedMeshesPerUrl[ name ] ++;
-
        if ( decodedMeshesPerUrl[ name ] === expectedMeshesPerUrl[ name ] ) {
-
            nCompletedUrls ++;
-
            model.add( modelParts[ name ] );
-
            if ( nCompletedUrls === nExpectedUrls ) {
-
-                // ALL DONE!!!
-
                allDoneCallback( model );
-
            }
-
        }
-
    };
-
    return meshCallback;
-
 };

-THREE.UTF8Loader.prototype.downloadModel = function ( geometryBase, materialBase, model, callback ) {
-
+THREE.UTF8Loader.prototype.downloadModel = function ( geometryBase, materialBase, model, callback, callbackProgress ) {
    var meshCallback = this.createMeshCallback( materialBase, model, callback );
-   this.downloadMeshes( geometryBase, model.urls, model.decodeParams, meshCallback );
-
+   this.downloadMeshes( geometryBase, model.urls, model.decodeParams, meshCallback, callbackProgress );
 };

-THREE.UTF8Loader.prototype.downloadModelJson = function ( jsonUrl, callback, options ) {
-
-   getJsonRequest( jsonUrl, function( loaded ) {
-
+THREE.UTF8Loader.prototype.downloadModelJson = function ( jsonUrl, callback, options, callbackProgress ) {
+   this.getJsonRequest( jsonUrl, function( loaded ) {
        if ( ! loaded.decodeParams ) {
-
            if ( options && options.decodeParams ) {
-
                loaded.decodeParams = options.decodeParams;
-
            } else {
-
                loaded.decodeParams = DEFAULT_DECODE_PARAMS;
-
            }
-
        }
-
        loaded.options = options;
-
        var geometryBase = jsonUrl.substr( 0, jsonUrl.lastIndexOf( "/" ) + 1 );
        var materialBase = geometryBase;
-
        if ( options && options.geometryBase ) {
-
            geometryBase = options.geometryBase;
-
            if ( geometryBase.charAt( geometryBase.length - 1 ) !== "/" ) {
-
                geometryBase = geometryBase + "/";
-
            }
-
        }
-
        if ( options && options.materialBase ) {
-
            materialBase = options.materialBase;
-
            if ( materialBase.charAt( materialBase.length - 1 ) !== "/" ) {
-
                materialBase = materialBase  + "/";
-
            }
-
        }
-
-       this.downloadModel( geometryBase, materialBase, loaded, callback );
-
+       this.downloadModel( geometryBase, materialBase, loaded, callback, callbackProgress );
    }.bind( this ) );
-
 };

-// XMLHttpRequest stuff
-
-function getHttpRequest( url, onload, opt_onprogress ) {
-
+THREE.UTF8Loader.prototype.getHttpRequest = function( url, onload, opt_onprogress ) {
    var LISTENERS = {
-
-        load: function( e ) { onload( req, e ); },
-        progress: function( e ) { opt_onprogress( req, e ); }
-
-    };
-
+           load: function( e ) { onload( req, e ); },
+           progress: function( e ) { opt_onprogress( e ); }
+   };
    var req = new XMLHttpRequest();
-   addListeners( req, LISTENERS );
-
+   this.addListeners( req, LISTENERS );
    req.open( 'GET', url, true );
    req.send( null );
 }

-function getJsonRequest( url, onjson ) {
-
-   getHttpRequest( url,
+THREE.UTF8Loader.prototype.getJsonRequest = function( url, onjson ) {
+   this.getHttpRequest( url,
         function( e ) { onjson( JSON.parse( e.responseText ) ); },
         function() {} );
-
 }

-function addListeners( dom, listeners ) {
-
+THREE.UTF8Loader.prototype.addListeners = function( dom, listeners ) {
     // TODO: handle event capture, object binding.
-
    for ( var key in listeners ) {
-
        dom.addEventListener( key, listeners[ key ] );
-
    }
 }
RemusMar commented 9 years ago

It's 100% backward compatible with the previous one. I didn't modify the JSON loader part because no one needs onProgress for a few hundred bytes. The major update is related to the downloadMesh part (the UTF8 file loader), because that's the one with MB involved. Feel free to replace the old file if you like.

mrdoob commented 9 years ago

As you can see on my previous post, many things changed. It's not clear what did actually change and I can't blindly replace the file. Also, seems like you removed the credits from all the original authors of the file.

RemusMar commented 9 years ago

I always remove all the comments inside of the downloaded files. Smaller files = faster download. Not to mention that it saves server bandwidth ...

Mugen87 commented 6 years ago

UTF8Loader has been removed via #14363