关于three.js:导入Zip文件

Import Zip Files

我使用的是OBJ格式,但是OBJ太重而无法下载,因此,我想以Zip格式上传OBJ文件,然后查看器将其解压缩并调用OBJLoader函数。
你知道什么是最好的方法吗?
谢谢,
拉法


除了最好的解决方案之外,您还无法传递缓冲区而不是URL到加载器,这实在是毫无意义的。我也需要它,所以我使用了@jimver的答案,但是更改了JSZip方法,因为它们已被弃用。请改用它(在我的情况下,我在文件STLLoader.js上进行了更改,因为我正在使用STL文件,但这适用于所有加载程序):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
THREE.STLLoader.prototype = {

constructor: THREE.STLLoader,

load: function ( url, onLoad, onProgress, onError ) {

    var scope = this;

    var loader = new THREE.XHRLoader( scope.manager );
    loader.setResponseType( 'arraybuffer' );
    loader.load( url, function ( text ) {

        if (url.split('/').pop().split('.')[1] == 'zip') {
                JSZip.loadAsync(text)
                .then(function (zip) {
                    return zip.file(Object.keys(zip.files)[0]).async("arrayBuffer");
                })
                .then(function success(text) {
                        onLoad( scope.parse( text ) );
                    }, function error(e) {
                        console.log(e);
                });
        }
        else {
            onLoad( scope.parse( text ) );
        }

    }, onProgress, onError );
},

// rest of the code

问题通过以下方式解决:

1)将jszip脚本添加到您的页面
2)转到OBJMTLLoader.js(约33行),并放置这10行以解压缩loader.load函数内部的zip(假设file.zip仅包含file.obj)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
loader.load( url, function ( text ) {


                if (url.split('/').pop().split('.')[1] == 'zip'){
                //- Uncompress url e.g.  http:// .... / PTERO.zip -> PTERO.obj -

                    // zip should contain only one file !

                    // uncompression object
                    var new_zip = new JSZip();

                    // uncompress
                    new_zip.load(text);

                    // the single file name convention
                    filename = url.split('/').pop().split('.')[0] +".obj";

                    // get the file content as text
                    text = new_zip.file(filename).asText();
                }
                //--------------------------------------------

                var object = scope.parse( text );

3)在Three.js的XHRLoader中添加这两行,以便在扩展名为zip时加载二进制文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 THREE.XHRLoader.prototype = {

    constructor: THREE.XHRLoader,

    load: function ( url, onLoad, onProgress, onError ) {

        var scope = this;

        var cached = scope.cache.get( url );

        if ( cached !== undefined ) {

            if ( onLoad ) onLoad( cached );
            return;

        }

        var request = new XMLHttpRequest();
        request.open( 'GET', url, true );


        // ----------  for zipped obj ------------
        if ( url.split('.').pop() == 'zip')
            request.responseType ="arraybuffer";
        //--------------------------------------

        request.addEventListener( 'load', function ( event ) {

        scope.cache.add( url, this.response );

        ...


解码器内置了gzip解码器。您根本不需要任何客户端代码。您需要做的就是确保服务器设置了正确的MIME类型。
请参阅:在提供压缩文件时使用什么"内容类型"标题?


我会尝试使用jszip

1
2
3
4
5
6
7
8
JSZipUtils.getBinaryContent('path/to/objzipped.zip', function(err, data) {
  if(err) {
    throw err; // or handle err
  }
  var zip = new JSZip(data);
  var objData = zip.file("objfile.obj").asText();
  var object3D = new OBJLoader().parse(objData); // ...
});

如果您确实要在浏览器中使用zip,

我认为您可以使用zip.js解压缩下载的文件,然后使用OLBJLoader.parse解析结果。