three.js加载gltf模型笔记

2,236 阅读2分钟

1. camera.up

加载的模型是一个房子,测量的时候z轴代码高度,但在3d中展示又是y轴才是向上的,所以要调整相机朝向

默认 this.camera.up.set(0,1,0) Y轴朝向上

image.png

修改后 this.camera.up.set(0,0,1) Z轴朝向上

image.png

2. rayCaster 坐标计算问题

直接上代码

      const clickCanvas = event => {
        mouse.x = ((event.clientX - canvas.offsetLeft) / canvas.clientWidth) * 2 - 1;
        mouse.y = -((event.clientY - canvas.offsetTop) / canvas.clientHeight) * 2 + 1;

        checkIntersection();
      };

      const checkIntersection = () => {
        raycaster.setFromCamera(mouse, camera);
        const intersects = raycaster.intersectObject(scene, true);
        // 具体业务
      };

在一些demo中往往是全屏展示的

// 监听鼠标的位置
window.addEventListener("click", (event) => {
  // 要求得中心坐标位置 X分量与Y分量应当在-1到1之间。   所以 * 2 - 1
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -((event.clientY / window.innerHeight) * 2 - 1);
  raycaster.setFromCamera(mouse, camera);
  let result = raycaster.intersectObjects(cubeArr);
  result.forEach((item) => {
    item.object.material = activeMaterial;
  });
});

但在实际开发中,cavnas并不一定是全屏, 这时候就要计算mouse对应的x y,参考大佬说明

blog.csdn.net/aazhoukeaa/…

image.png

这东西有个专业名词

标准化设备坐标(Normalized Device Coordinates, NDC)

  • bug

使用offsetTop需要注意,跟父级postion:relative有关, 建议使用getBoundingClientReact().top 替换

image.png

image.png

3. mesh选中样式问题

由于对象引用类型,修复material对象的值,必须clone一份

    obj.material = obj.material.clone();
    obj.material.color.set(this.defaultColor);
    // 自发光
    obj.material.emissive = obj.material.color;

选中objecet其中的一个mesh,但需要修改整体object的mesh

        mesh.traverse(obj => {
          if (obj && obj.material) {
            obj.material = obj.material.clone();
            obj.material.color.set("#095aff");
            obj.material.emissive = obj.material.color;
          }
        });

也可以通过mesh.parent再找到所有的children处理也一样

4. 通过name找object

let mesh = this.scene.getObjectByName(name);

5. 加载本地gltf调试问题

由于webpack的原因,原有的文件路径会换,直接使用相对路径加载会报json 语法错误

    loadGlTF() {
      const gltfLoader = new GLTFLoader();
      this.loading = true;
      gltfLoader.load(
        "/models/2.gltf",
        gltf => {
          console.log("sceneData", gltf);
          this.sceneData = gltf;
          this.$nextTick(() => {
            this.$refs.model.loadGlTF();
            this.loading = false;
          });
        },
        process => {
          console.log(process);
          console.log("加载完成的百分比" + (process.loaded / process.total) * 100 + "%");
        },
        err => {
          this.loading = false;
          console.log("gltf load err", err);
        },
      );
    },

由于业务加载的为远程链接文件,在调研阶段我直接把文件放vue项目中的public/modles文件夹下

如果生产中还是使用使用本地文件主话,建议在webpack的loader添加对应的rule

      {
        test: /.(gltf)$/,
        loader: "gltf-webpack-loader"
      },

然后在开发代码中import(xxxx) 加载路径使用