• 记录Three.js的简单使用,Three.js在vue3.x中导入.pcd三维模型文件


    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

    本文说明

    本文主要简单介绍了,在Vue3.x项目中如何简单的使用Three.js,导入PCD三维模型文件。

    模型显示

    项目实现

    第一步

    首先创建一个vue3.x,的项目,然后需要先有一个 .pcd三维模型文件,如果有的话,将三维点云文件放在如下图的文件夹里,如果没有的话,百度云盘(链接:pan.baidu.com/s/1TM2gKCep… )

    第二步

    在安装Three.js前,需要安装Babel,来编译ES6语法。

    参考:

    vue安装babel-polyfill插件,解决低版本浏览器不支持ES6新语法的问题

    www.cnblogs.com/chenyingyin…

    vuecli3 如何使用babel

    www.csdn.net/tags/MtTaMg…

    好像也可以在创建项目的时候,安装Babel

    vue create vue3-test

    第三步

    需要在vue3.x项目中安装Three.js

    npm install three@0.128.0
    
    npm install three-orbit-controls
    
    npm i --save three-css2drender

    依次安装,也可以一起安装

    npm install --save three@0.128.0 three-orbit-controls three-css2drender

    第四步

    在项目中使用,以下是整个完整代码

    <template>
    
      <div style="height: 100%;  100%">
    
        <div id="three" style="height: 100%;  100%"></div>
    
      </div>
    
    </template>
    
    
    
    <script>
    
    // 引入Three.js
    
    import * as THREE from "three";
    
    // 引入PCD加载器
    
    import { PCDLoader } from "three/examples/jsm/loaders/PCDLoader.js"; // 注意是examples/jsm
    
    // 引入模型控制器
    
    import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; // 放大缩小旋转等控制操作
    
    // 创建一个时钟对象Clock
    
    var clock = new THREE.Clock();
    
    // 设置渲染频率为30FBS,也就是每秒调用渲染器render方法大约30次
    
    var FPS = 30;
    
    var renderT = 1 / FPS; //单位秒  间隔多长时间渲染渲染一次
    
    // 声明一个变量表示render()函数被多次调用累积时间
    
    // 如果执行一次renderer.render,timeS重新置0
    
    var timeS = 0;
    
    export default {
    
      components: {},
    
      data() {
    
        return {
    
          animationId: null,
    
          elem: null,
    
          scene: null,
    
          // mesh: null, //网格模型对象
    
          camera: null, //相机对象
    
          renderer: null, //渲染器对象
    
          loader: null,
    
          controls: null,
          
          publicPath: process.env.BASE_URL // public
    
        };
    
      },
    
      beforeDestroy() {
    
        this.destroyModel();
    
      },
    
      created() {},
    
      mounted() {
    
        // 初始化模型
        
        this.initModel(`${this.publicPath}static/models/pcd/Zaghetto.pcd`, "three")
    
      },
      methods: {
    
        initModel(pcdPath, domName) {
    
          console.log("开始初始化模型文件");
    
          this.elem = document.getElementById(domName);
    
          // 相机CanvasRenderer
    
          this.camera = new THREE.PerspectiveCamera(
    
            30, // 视野
    
            this.elem.clientWidth / this.elem.clientHeight, // 纵横比
    
            0.1, // 近平面
    
            1000 // 远平面
    
          );
    
          // 渲染器
    
          this.renderer = new THREE.WebGLRenderer({
    
            antialias: true,
    
            alpha: true
    
          });
    
          this.renderer.setClearColor(new THREE.Color(0x303030)); // 背景色
    
          this.renderer.setSize(this.elem.clientWidth, this.elem.clientHeight);
    
          this.elem.appendChild(this.renderer.domElement);
    
          this.scene = new THREE.Scene(); // 场景
    
          this.loader = new PCDLoader(); //PCD加载器
    
          const THIS = this;
    
          //第一层  捕捉报错
    
          try {
    
            //加载PCD文件
    
            THIS.loader.load(
    
              pcdPath,
    
              function(points) {
    
                // console.log(points);
    
                // 模型点位大小
    
                // points.material.size = 0.02;
    
                points.material.color = new THREE.Color(0x00ffff); // 模型颜色
    
                THIS.scene.add(points);
    
                // 构造盒子
    
                var middle = new THREE.Vector3();
    
                points.geometry.computeBoundingBox();
    
                points.geometry.boundingBox.getCenter(middle);
    
                points.applyMatrix4(
    
                  new THREE.Matrix4().makeTranslation(
    
                    -middle.x,
    
                    -middle.y,
    
                    -middle.z
    
                  )
    
                );
    
                // 比例
    
                var largestDimension = Math.max(
    
                  points.geometry.boundingBox.max.x,
    
                  points.geometry.boundingBox.max.y,
    
                  points.geometry.boundingBox.max.z
    
                );
    
                THIS.camera.position.y = largestDimension * 1;
    
                THIS.animate();
    
                THIS.controls = new OrbitControls(
    
                  THIS.camera,
    
                  THIS.renderer.domElement
    
                );
    
                THIS.controls.addEventListener("change", THIS.animate); // 监听鼠标、键盘事件  放大缩小等
    
              },
    
              function(xhr) {
    
                // console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
    
              },
              //第二层 捕捉报错
              function(error) {
                THIS.$Message.error("模型地址不对,请稍候再试!");
    
              }
    
            );
    
          } catch (error) {
            THIS.$Message.error("模型地址不对,请稍候再试!");
    
          }
    
        },
        
        // 监听鼠标、键盘事件  放大缩小等
    
        animate() {
          this.animationId = requestAnimationFrame(this.animate);
    
          //.getDelta()方法获得两帧的时间间隔
    
          var T = clock.getDelta();
    
          timeS = timeS + T;
    
          // requestAnimationFrame默认调用render函数60次,通过时间判断,降低renderer.render执行频率
    
          if (timeS > renderT) {
    
            // 控制台查看渲染器渲染方法的调用周期,也就是间隔时间是多少
    
            // console.log(`调用.render时间间隔`, timeS * 1000 + "毫秒");
    
            this.renderer.render(this.scene, this.camera); //执行渲染操作
    
            //renderer.render每执行一次,timeS置0
    
            timeS = 0;
    
          }
    
        },
    
        // 销毁模型
    
        destroyModel() {
    
          console.log("销毁模型");
    
          clearTimeout();
    
          try {
    
            this.scene.clear();
    
            this.renderer.dispose();
    
            this.renderer.forceContextLoss();
    
            this.renderer.content = null;
    
            cancelAnimationFrame(this.animationId); // 去除animationFrame
    
            const gl = this.renderer.domElement.getContext("webgl");
    
            gl && gl.getExtension("WEBGL_lose_context").loseContext();
    
            console.log("销毁成功");
    
          } catch (e) {
    
            console.log(e);
    
            console.log("销毁失败");
    
          }
    
        }
    
      }
    
    };
    
    </script>
    <style  scoped>
    </style>

    引用

    Three.js中文网 www.webgl3d.cn/

    GitHub上的Three.js github.com/mrdoob/thre…

    3D模型文件下载,既有免费的也有收费的,加载较慢 free3d.com/

    本文转载于:

    https://juejin.cn/post/7126461520417914887

    如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

     

  • 相关阅读:
    jquery实现下拉框多选
    最好的Angular2表格控件
    CSS3阴影 box-shadow的使用和技巧总结
    存档2
    Python的编码注释# -*- coding:utf-8 -*-
    路由器与交换机区别
    TCP的流量控制
    TCP的拥塞控制
    存储管理之页式、段式、段页式存储
    什么是死锁?其条件是什么?怎样避免死锁?
  • 原文地址:https://www.cnblogs.com/smileZAZ/p/16628571.html
Copyright © 2020-2023  润新知