You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js中如何在GLTFLoader外部获取GLB模型的Geometry

解决方案

问题核心在于GLTFLoader.load是异步操作,你原代码中后续的Geometry处理逻辑在模型加载完成前就执行了,自然无法获取到正确的模型数据。需要将所有依赖模型Geometry的逻辑移到加载完成后的回调中,或者使用async/await处理异步流程,确保模型加载完成后再操作Geometry。

以下是修改后的reset函数:

// 改为async函数,支持await异步加载
async function reset() {
  // dispose of the mesh if it exists
  if (targetMesh) {
    targetMesh.geometry.dispose();
    targetMesh.material.dispose();
    scene.remove(targetMesh);
  }

  // 包装loader.load为Promise,支持await
  const loadGLB = (url) => new Promise((resolve, reject) => {
    const loader = new GLTFLoader();
    loader.load(
      url,
      resolve,
      (xhr) => console.log((xhr.loaded / xhr.total) * 100 + "% loaded"),
      reject
    );
  });

  try {
    // 等待模型加载完成
    const glb = await loadGLB("teeth.glb");
    
    // 遍历GLB场景,提取Mesh的Geometry(假设模型中只有一个Mesh,若有多个可自行调整逻辑)
    let geometry = null;
    glb.scene.traverse(child => {
      if (child.isMesh && !geometry) {
        // 克隆Geometry,避免修改原模型的Geometry
        geometry = child.geometry.clone();
        // 移除原模型,后续使用处理后的targetMesh
        scene.remove(glb.scene);
      }
    });

    if (!geometry) {
      console.error("未在GLB模型中找到Mesh对象");
      return;
    }

    // 执行原有的Geometry处理逻辑
    geometry.deleteAttribute("uv");
    geometry = BufferGeometryUtils.mergeVertices(geometry);
    geometry.attributes.position.setUsage(THREE.DynamicDrawUsage);
    geometry.attributes.normal.setUsage(THREE.DynamicDrawUsage);
    geometry.computeBoundsTree({ setBoundingBox: false });

    // 创建新的Mesh并添加到场景
    targetMesh = new THREE.Mesh(geometry, material);
    targetMesh.frustumCulled = false;
    scene.add(targetMesh);

    // 初始化并更新BVH Helper
    if (!bvhHelper) {
      bvhHelper = new MeshBVHHelper(targetMesh, params.depth);
      if (params.displayHelper) {
        scene.add(bvhHelper);
      }
    }
    bvhHelper.mesh = targetMesh;
    bvhHelper.update();

  } catch (error) {
    console.log("模型加载出错:", error);
  }
}

关键修改点:

  • 将reset改为async函数,通过Promise包装loader.load实现异步等待,确保模型加载完成后再处理Geometry。
  • 遍历GLB场景中的子对象,找到Mesh类型的对象并克隆其Geometry(避免修改原模型数据)。
  • 所有依赖Geometry的逻辑(合并顶点、创建Mesh、更新BVH等)都放在模型加载完成后的代码块中。
  • 添加了错误捕获,处理模型加载失败的情况。

内容的提问来源于stack exchange,提问作者AshhadDevLab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 00:47:50