加载多个 OBJ 文件和多个纹理

Load multiple OBJ-files together with multple textures

使用 ThreeJS 上的许多示例,我能够将多个 OBJ 文件加载到我的场景中。我还可以加载多个图像作为纹理。然而,纹理被分配给 'order of appearance' 中的对象,因此,有时错误的图像被分配给 OBJ 文件。

我从 JavaScript 数组中检索 OBJ 文件和纹理列表,比方说:

…
"arr_threejs": [{
    "geometry": "my_first_object.obj",
    "material_uvmap": "my_first_texture.jpg",

}, {
    "geometry": "my_second_object.obj",
    "material_uvmap": "my_second_object.obj",

}],…

然后,我使用这个 'loader' class 来加载纹理:

for (var i = 0; i < arr_threejs.length; i++) {

    var loader = new THREE.ImageLoader(manager);

    str_material_uvmap_url = arr_threejs[i].material_uvmap;

    loader.load(str_material_uvmap_url, function (image) {

        console.log(image);
        var index = textures.push(new THREE.Texture()) - 1;
        textures[index].image = image;
        textures[index].needsUpdate = true;

    });
}

同样,几何:

var loader = new THREE.OBJLoader(经理);

for (var i = 0; i < arr_threejs.length; i++) {

    str_model_url = arr_threejs[i].geometry;

    loader.load(str_model_url, function (object, i) {

        var index = get_index_by_url(str_model_url); //doesn't work
        objects[index] = object;

        objects[index].traverse(function (child) {

            if (child instanceof THREE.Mesh) {

                child.material.map = textures[index];
                child.material.side = THREE.DoubleSide;
            }
        });

        scene.add(objects[index]);

    }, onProgress, onError);
}

看来我无法在回调函数中知道我正在处理什么对象或什么纹理。 var index = get_index_by_url(str_model_url); 不起作用,因为 str_model_url 没有传递为争论。

所以,我的问题是,

具体来说:

有没有办法知道我要加载的图像或对象的索引?

或者一般来说:

是否有标准的方法来加载多个带有纹理的 OBJ 文件?

您可以使用匿名函数。例如:

loader.load(str_model_url, (function (url,scale) { return function (object, i) {
        console.log( url );
        console.log( scale );
    }}) (str_model_url, 0.5)
    , onProgress
    , onError
);

这是在我的代码中实现的@stdob 答案:

   // MODEL

    // model - LOAD TEXTURE

    for (var i = 0; i < arr_threejs.length; i++) {

        var loader = new THREE.ImageLoader(manager);

        str_material_uvmap_url = arr_threejs[i].material_uvmap;

        loader.load(str_material_uvmap_url, (function (url, index) {
                return function (image, i) {
                    textures[index] = new THREE.Texture();
                    textures[index].image = image;
                    textures[index].needsUpdate = true;
                }
            })(str_material_uvmap_url, i)
            , onProgress
            , onError
        );
    }

    // model - LOAD OBJECT

    var loader = new THREE.OBJLoader(manager);

    for (var i = 0; i < arr_threejs.length; i++) {

        str_model_url = arr_threejs[i].geometry;

        loader.load(str_model_url, (function (url, index) {
                return function (object, i) {

                    objects[index] = object;

                    objects[index].traverse(function (child) {

                        if (child instanceof THREE.Mesh) {
                            child.material.map = textures[index];
                            child.material.side = THREE.DoubleSide;
                        }
                    });

                    scene.add(objects[index]);

                }
            })(str_model_url, i)
            , onProgress
            , onError
        );
    }