Hi. I’m building a scene with multiple similar GLTF models. To optimize my code I would like to set all my models in variables an only call a function name, the path of the model and a visibility boolean with a for loop. I cant turn my head around to make this to work. Could someone please tell me what I’m doing wrong?
let objectList = [
'Head_Happy',
'Tongue_Inside',
'Theets_Regular',
];
let objectModels = [
"Head_Happy.gltf",
"Tongue_Inside.gltf",
"Theets_Regular.gltf",
];
let objectVisibility = [
false,
true,
true,
];
for (let i = 0; i < objectList.length; i++) {
loader.load( 'objectModels[i]', function( objectList[i] ) {
scene.add( objectList[i].scene );
objectList[i].scene.traverse( function( child ) {
if ( child.isMesh ) {
child.castShadow = true;
child.receiveShadow = true;
}
} );
objectList[i].scene.visible = objectVisibility[i];
render();
} );
}
it’s quite difficult to understand your question, you may need to rephrase the problem you’re experiencing and what is the result you’re getting… my first thought is that your for loop is excecuting the next iterated load function before the previous model is loaded, a better way to ensure the previous model is loaded before calling the next iteration would be an approach like this…
let i = 0
function loadNext(){
loader.load( 'objectModels[i]', function( objectList[i] ) {
scene.add( objectList[i].scene );
objectList[i].scene.traverse( function( child ) {
if ( child.isMesh ) {
child.castShadow = true;
child.receiveShadow = true;
}
} );
objectList[i].scene.visible = objectVisibility[i];
i++
if( i < objectList.length){
loadNext()
}
render();
} );
}
loadNext()
The code above looks for GLTF file named “objectModels[i]” (this is actual name, with square brackets in it). Maybe you want to load the GLTF file with a name stored in objectModels[i]. In this case, try without the single quotes:
Also, the argument of the call-back function cannot be objectList[i] . It must be a single identifier.
let object = [ 'head', 'hairs', 'mouth'];
let i = 0
function loadNext() {
loader.load( object[i], function( o ) {
scene.add( o );
i++
if( i < object.length){
loadNext()
}
render();
} );
}
loadNext()
for( let i = 0; i<objectNames.length; i++ )
{
var filename = ...;
loader.load( filename, gltf=>loaded(i,gltf.scene) );
}
function loaded( index, gltf )
{
// do whatever you want with the model
objects[index] = gltf;
scene.add( gltf );
}
three is inherently async, all loaders are, how are you not using async/await? nested callbacks have been abolished, no good idea to go back to this pattern as it would complicate matters to no end and create race conditions.
the following will fetch all assets in parallel, no waterfalls, next line everything’s available and you can do with it what you want.