Reputation: 1365
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
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
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