Search code examples
javascriptthree.jsreact-three-fiber

How to access a glb model outside the loader | Threejs


I am using a GLTFLoader in threejs and a glb model init. I want to use that model outside of the loader, I have already read a lot of Topics but none of them help me fix my problem.

Here's the example I am using: sculpt.js

Here's my code:


init();
render();

// reset the sculpt mesh
function reset() {
  // dispose of the mesh if it exists
  if (targetMesh) {
    targetMesh.geometry.dispose();
    targetMesh.material.dispose();
    scene.remove(targetMesh);
  }

  // merge the vertices because they're not already merged
  const loader = new GLTFLoader();

  // Load a glTF resource
  loader.load(
    // resource URL
    "teeth.glb",
    // called when the resource is loaded
    function (glb) {
      scene.add(glb.scene);

      glb.animations; // Array<THREE.AnimationClip>
      glb.scene; // THREE.Group
      glb.scenes; // Array<THREE.Group>
      glb.cameras; // Array<THREE.Camera>
      glb.asset; // Object
    },
    // called while loading is progressing
    function (xhr) {
      console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
    },
    // called when loading has errors
    function (error) {
      console.log("An error happened");
    }
  );
  geometry.deleteAttribute("uv");
  geometry = BufferGeometryUtils.mergeVertices(geometry);
  geometry.attributes.position.setUsage(THREE.DynamicDrawUsage);
  geometry.attributes.normal.setUsage(THREE.DynamicDrawUsage);
  geometry.computeBoundsTree({ setBoundingBox: false });

  // disable frustum culling because the verts will be updated
  targetMesh = new THREE.Mesh(geometry, material);
  targetMesh.frustumCulled = false;
  scene.add(targetMesh);

  // initialize bvh helper
  if (!bvhHelper) {
    bvhHelper = new MeshBVHHelper(targetMesh, params.depth);
    if (params.displayHelper) {
      scene.add(bvhHelper);
    }
  }

  bvhHelper.mesh = targetMesh;
  bvhHelper.update();
}


I only need help in the reset function just want the loader to export the model outside the loader as geometry.

Any help would be grateful.


Solution

  • The problem you are facing is that GLTFLoader.load() is an asynchronous function. So all reset operations are done before your file.glb is loaded. One option you have is to do the rest of the operations inside the GLTFLoader.load() callback (onLoad).

    To get only the geometries of a loaded scene you can traverse() the scene, check if each object is a Mesh and if so get the geometry, as follow:

    glb.scene.traverse(obj => {
       if (obj.isMesh) {
         console.log(obj.geometry);
       }
    });