How do I load 2 models at once?

Hello, I have started using Three.js just yesterday and I gotta say Im really lost in this thing. I can not manage to load two models at once. Let me explain. Im want to make a weapon inspect, however, the weapon model I have has 2 parts, one contains lenses and the other one the entire gun. I tried looking at how others solved it, but seems like everyone made it so multiple kinds of weapons can be inspected and so instead of directly using urls it uses variables pulled from search etc. So Id like to ask.

				const loader = new OBJLoader( manager );
				loader.load( 'AWP_m1.obj', function ( obj ) {

					object = obj;
					object.scale.x = object.scale.y = object.scale.z = 5;

				}, onProgress, onError );

this is my first model. I want to load two models at once, so they look like one. I tried using loader.load() twice but that had no effect on the result. Thanks and please, do not just close my thread…

Hi @ItzArty,

I think loaders do not support multiple model loading however you can make a chain of loads and attach other parts of the model when they are loaded.

const loader = new OBJLoader( manager );
loader.load( 'your_model_part_1.obj', function ( part_1) {
    loader.load( 'your_model_part_2.obj', function ( part_2) {
       part_1.add(part_2)
    }); 
});

Hi @Sarge, so I tried the method you suggested, but it seems to have no effect aswell. Since I am new to Three I used an example scene, so maybe the load function is wrong, since as I see it adds every element to the scene, so Im not sure if that does not cause your suggestion to not work properly, since here you suggested using add, which is executed by the load function

				function loadModel() {

				object.traverse( function ( child ) {

					if ( child.isMesh ) child.material.map = texture;

				} );

				object.position.y = 0;
				scene.add( object );

			}

Fixed! I had just to move let object2 above let object and it worked, weird

1 Like

You can actually start two parallel loading processes. So the following is valid:

const loader = new OBJLoader( manager );
loader.load( 'your_model_part_1.obj', function ( part_1 ) {
    // do something with part_1
});
loader.load( 'your_model_part_2.obj', function ( part_2 ) {
    // do something with part_2
});
2 Likes

You could also use Promise.all(), to load all models in parallel (not in a chain).

Here an example with the GLTFLoader:

// init loader
const loader = new THREE.GLTFLoader()

// make async loader
const loadAsync = url => {
  return new Promise(resolve => {
    loader.load(url, gltf => {
      resolve(gltf)
    })
  })
}

// load both models in parallel
Promise.all([loadAsync('/assets/glb/robot.glb'), loadAsync('/assets/glb/suzanne.glb')]).then(models => {
  // get what you need from the models array
  const robot = models[0].scene.children[0]
  const suzanne = models[1].scene.children[0]

  // add both models to the scene
  scene.add(robot)
  scene.add(suzanne)
})
4 Likes

Thank you all for your help, I really do appreciate it!

This code is actually not required. Just use Loader.loadAsync().

3 Likes

Wow. Did not know there was such a function included. Thanks!
Gave it even the same name :joy:

4 Likes

How do you bind the on Error in the promise ? I have done this according to the Loader.loadAsync() documentation but reject does not exist: :frowning:
“Uncaught (in promise) TypeError: promiseLoad.reject is not a function”

					let promiseLoad = loader.loadAsync(url);

					function resolved(result) {
						console.log('Resolved');
					}

					function rejected(result) {
						console.error(result);
					}

					promiseLoad.reject(new Error('fail')).then(resolved, rejected);

					var gltfObject = await promiseLoad;