0
votes

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?

2
Why not just do one loop and load the object then load its image in it's complete function? Then you could have a reference to the correct object.2pha
Thanks! Sorry, I don't quite get it. Yes, I can do a loop do load all the objects, but in the 'complete'-function, how do I know which object I'm acting on? Sorry if this is all very trivial, but I can't wrap my mind around it...Ideogram

2 Answers

1
votes

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

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