How can we Load multiple ObjLoader with its own different texture!

It is only Loading Last model which in the array

const texture = new THREE.Texture();
const manager = new THREE.LoadingManager();
const loader = new THREE.ImageLoader(manager);
for (const uploadFiles of data.uploadedThreeDModel) {
  let loadedMaterials = [];
     manager.onLoad = () => {
        if (loadedMaterials.length > 0) {
          const objLoader = new OBJLoader();
          objLoader.setMaterials(loadedMaterials[0]);
          objLoader.load(uploadFiles.url.url, (object) => {
            object.traverse((child) => {
              if (child instanceof THREE.Mesh) {
                child.material =
                  child.material || new THREE.MeshPhongMaterial();
                child.material['map'] = texture;
              }
            });
            object.receiveShadow = true;
            object.castShadow = true;
            object.name = 'Obj-uploadFiles.content.name';
            object.matrixAutoUpdate = true;
            object.updateMatrix();
            scene.add(object);
            meshs.push(object);
            transformControl.attach(object);
          });
        }
      };

      for (let i = 0; i < uploadFiles.arrOfTexture.length; i++) {
        loader.load(uploadFiles.arrOfTexture[i], (img) => {
          if (img) {
            texture.image = img;
            texture.mapping = THREE.UVMapping;
            texture.needsUpdate = true;
          }
        });
      }
      // for multiple mtl files loader
      const mtlLoader = new MTLLoader(manager);
      mtlLoader.load(uploadFiles.mtl.url, (materials) => {
        materials.preload();
        loadedMaterials.push(materials);
      });

}

It’s hard to tell something without debugging but the above line is wrong. You overwrite the onLoad() handler over and over again. So only the last assignment will be valid. It’s probably necessary to use an instance of LoadingManager per model.

2 Likes

how to use LoadingManager if the code I have is like this:

let patternArray = ["hiro", "pattern-markerobj1"];
      let colorArray = [0xff8800, 0xffff00, ];
      let mtlobj = ['fish-2', 'percobaan', ];
      let scale = [0.25, 0.0025, ];

      for (let i = 0; i < 2; i++) {

        markerRoot1 = new THREE.Group();
        scene.add(markerRoot1);

        let markerControls1 = new THREEx.ArMarkerControls(arToolkitContext, markerRoot1, {
          type: 'pattern',
          patternUrl: "data/" + patternArray[i] + ".patt",
        })

        let geometry1 = new THREE.PlaneBufferGeometry(1, 1, 4, 4);

        // let texture = loader.load( 'images/earth.jpg', render );
        let material1 = new THREE.MeshBasicMaterial({
          color: colorArray[i],
          opacity: 0.0005
        });
        mesh1 = new THREE.Mesh(geometry1, material1);
        mesh1.rotation.x = -Math.PI / 2;
        markerRoot1.add(mesh1);

        function onProgress(xhr) {
          console.log((xhr.loaded / xhr.total * 100) + '% loaded');
        }

        function onError(xhr) {
          console.log('An error happened');
        }

        new THREE.MTLLoader()
          .setPath('models/')
          .load(mtlobj[i] + '.mtl',function (materials) {
            materials.preload();
            new THREE.OBJLoader()
              .setMaterials(materials)
              .setPath('models/')
              .load(mtlobj[i] + '.obj', function (group) {
                mesh0 = group.children[0];
                mesh0.material.side = THREE.DoubleSide;
                mesh0.position.y = 0.25;
                mesh0.scale.set(scale[i], scale[i], scale[i]);
                markerRoot1.add(mesh0);
              }, onProgress, onError);
          });

      }

Create an instance of LoadingManager and apply it to the ctor of all loaders you are going to create. In the next step, assign an onLoad() callback to the manager so you can execute code when everything has been loaded.