Ideogram
Ideogram

Reputation: 1365

Load multiple OBJ-files together with multple textures

Using the many examples on ThreeJS, I'm able to load multiple OBJ files into my scene. I'm also able to load multiple images as textures. However, the textures get assigned to the objects in 'order of appearance' and therefore, sometimes the wrong image gets assigned to the OBJ files.

I retrieve a list of OBJ files and textures from a JavaScript array, let's say:

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

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

}],…

Then, I use this 'loader' class to load the textures:

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;

    });
}

And, simillary, the geometry:

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 (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);
}

It seems I have no way in the callback function to know what object or what texture I'm dealing with. var index = get_index_by_url(str_model_url); doesnt work, because str_model_url isn't passed as arguement.

So, my question is,

specifically:

Is there a way to know the index of the image or object that I'm trying to load?

or generally:

Is there a standard way to load multple OBJ-files with textures?

Upvotes: 0

Views: 1236

Answers (2)

Ideogram
Ideogram

Reputation: 1365

Here's @stdob answer implemented in my code:

   // 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
        );
    }

Upvotes: 0

stdob--
stdob--

Reputation: 29147

You can use anonymus functions. For example:

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
);

Upvotes: 1

Related Questions