Three.js 加载glb模型

时间:2024-07-16 17:53:38

引入资源

import * as THREE from "three";
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
 loadModel(option) {
    console.log("option1", option);
    let model = null;
    const loader1 = new GLTFLoader();
    console.log("loader1", loader1);
    loader1.load(option.url, (gltf) => {
      model = gltf.scene;
      model.position.set(option.x, option.y, option.z);
      // 模型中添加
      this.scene.add(gltf.scene);
    });
    console.log("model1111", model);
    return model;
  },  

使用

let option = {
    url: "./model/CesiumAir/Cesium_Air.glb",
    x: 15,
    y: 5,
    z: 0,
  };
  ffThree.loadModel(option);

异步加载

GLTFLoaderload方法是异步的,意味着它会在加载完成前立即返回,并且不会阻塞后续代码的执行。因此,当你在加载完成前访问model变量时,它仍然是null,因为加载过程尚未完成。

执行顺序问题

让我们来分析一下你的代码执行顺序:

  1. 创建loader1实例const loader1 = new GLTFLoader();
  2. 调用loader1.load()loader1.load(option.url, (gltf) => {...});
    • 此时,loader1.load开始加载模型,但是它是异步操作,会立即返回,继续执行后续代码。
  3. 打印model变量console.log("model1111", model);
    • 在加载完成之前,这行代码会打印model1111 null,因为model还没有被赋值。
  4. 返回modelreturn model;
    • 函数会立即返回null,因为model还没有被赋值为加载完成的模型。

使用Promise对象 

一种常见的方法是利用Promise对象或者回调函数来处理异步加载的结果。例如,可以修改你的函数,使其返回一个Promise对象,当模型加载完成时,Promise对象resolve模型对象。

 loadModelPromise(option) {
    return new Promise((resolve, reject) => {
      const loader1 = new GLTFLoader();
      loader1.load(
        option.url,
        (gltf) => {
          const model = gltf.scene;
          model.position.set(option.x, option.y, option.z);
          this.scene.add(model);
          resolve(model); // 将加载的模型传递给Promise的resolve函数
        },
        undefined,
        reject
      );
    });
  },
  • loadModel函数现在返回一个Promise对象,当模型加载成功后,Promise会resolve为加载的模型对象。
  • 在加载成功的回调函数中,我们通过调用resolve(model)来传递加载的模型对象。

使用

 let option = {
    url: "./model/CesiumAir/Cesium_Air.glb",
    x: -15,
    y: 5,
    z: 0,
  };
  loadModelPromise(option).then((res) => {
    console.log("得到加载的glb模型,可以在这对其修改", res);
    // res.scale.set(0.1, 0.1, 0.1);
  });

效果