vue使用three.js加载obj和mtl

①构建三维坐标,代码如下

<!--  -->
<template>
  <div id="container"></div>
</template>

<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
import * as THREE from "three";
import { OBJLoader, MTLLoader } from "three-obj-mtl-loader";
const OrbitControls = require("three-orbit-controls")(THREE);
import Stats from "stats-js";
export default {
  //import引入的组件需要注入到对象中才能使用
  components: { THREE, OBJLoader, MTLLoader, OrbitControls, Stats },
  props: {},
  data() {
    //这里存放数据
    return {};
  },
  //监听属性 类似于data概念
  computed: {},
  //监控data中的数据变化
  watch: {},
  //方法集合
  methods: {
    init() {
      var scene, camera, renderer, controls;
      scene = initScene();

      renderScene();
      // 控制器,监听鼠标事件
      function renderScene() {
        renderer.render(scene, camera);
      }
      // 场景自适应
      window.addEventListener("resize", onWindowResize, false);
      function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
      }
      function initScene() {
        // 创建场景
        var scene = new THREE.Scene();
        // 创建相机
        camera = new THREE.PerspectiveCamera(
          75,
          window.innerWidth / window.innerHeight,
          0.01,
          1000
        );
        //创建渲染器
        renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setClearColor(0xffffff, 0);
        renderer.setPixelRatio(window.devicePixelRatio);
        document.getElementById("container").appendChild(renderer.domElement);

        // 创建坐标轴
        var axes = new THREE.AxesHelper(100);
        scene.add(axes);

        camera.position.x = 1.8;
        camera.position.y = 0.6;
        camera.position.z = 2.7;
        camera.lookAt(scene.position);
        scene.add(camera);

        // 控制器,监听鼠标事件
        controls = new OrbitControls(camera, renderer.domElement);
        controls.addEventListener("change", renderScene);
        return scene;
      }
    },
    animate() {},
  },
  //生命周期 - 创建完成(可以访问当前this实例)
  created() {},
  //生命周期 - 挂载完成(可以访问DOM元素)
  mounted() {
    this.init();
  },
  beforeCreate() {}, //生命周期 - 创建之前
  beforeMount() {}, //生命周期 - 挂载之前
  beforeUpdate() {}, //生命周期 - 更新之前
  updated() {}, //生命周期 - 更新之后
  beforeDestroy() {}, //生命周期 - 销毁之前
  destroyed() {}, //生命周期 - 销毁完成
  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
};
</script>
<style  scoped>
</style>

②加载obj文件

  // 创建objLoader对象
      var loader = new OBJLoader();
      loader.load("../../static/536.obj", function (obj) {  // 调用OBJ的loader函数,加载成功会有个回调函数,参数obj就是模型加载成功后的网格Mesh实例对象
        scene.add(obj);
        // 页面加载成功后没有立即渲染模型,调用立即渲染函数
        renderScene();
      });

③未看见模型,原因:未设置光源,因此,设置光源

④ 设置网格对象的参数


      // 创建objLoader对象
      var loader = new OBJLoader();
      loader.load("../../static/536.obj", function (obj) {  // 调用OBJ的loader函数,加载成功会有个回调函数,参数obj就是模型加载成功后的网格Mesh实例对象
        // 调试发现模型会在y轴上方的,我们希望在y轴的下方一些
        // 网格模型按xyz进行放缩
        obj.scale.set(2,2,2);

        obj.position.y = -65;
        obj.position.x = -1045;
        obj.position.z = -50;
         // 几何体绕着x轴旋转45度
         obj.rotateX(Math.PI / 6);
        scene.add(obj);
        // 页面加载成功后没有立即渲染模型,调用立即渲染函数
        renderScene();
      });

⑤贴图

  // 给模型穿衣服,加载uv网格图片,以下代码写在模型加载上面
      const textureLoader = new THREE.TextureLoader();
      // 下载地址:https://github.com/mrdoob/three.js/blob/master/examples/textures/uv_grid_opengl.jpg
      console.log("texture对象初始化成功");


  // 创建objLoader对象
      var loader = new OBJLoader();
      loader.load("../../static/536.obj", function (obj) {
        // 调用OBJ的loader函数,加载成功会有个回调函数,参数obj就是模型加载成功后的网格Mesh实例对象
        // 调试发现模型会在y轴上方的,我们希望在y轴的下方一些

        // 遍历子网格
        obj.traverse(function (child) {
          if (child.isMesh) {
            // 纹理设置
            console.log("遍历子网格");
            child.material.map = texture;
          }
        });
        // 网格模型按xyz进行放缩
        obj.scale.set(2, 2, 2);

        obj.position.y = -65;
        obj.position.x = -1045;
        obj.position.z = -50;
        // 几何体绕着x轴旋转45度
        obj.rotateX(Math.PI / 6);
        scene.add(obj);
        // 页面加载成功后没有立即渲染模型,调用立即渲染函数
        renderScene();
      });

⑥管理器

初始化管理器

// 配置加载管理器类,获取加载进度和是否加载出错
const manager = new THREE.LoadingManager();
// 参数1:正在加载的模型,参数2:已经加载的模型 参数3:总的模型数量
manager.onProgress = function(item,loaded,total){
		console.log(item,loaded,total);
}

 预先定义一个存放OBJ模型的变量

// 预先定义一个存放OBJ模型的变量
var object;

编写一个模型加载完成 callback函数

// 编写一个模型加载完成 callback函数
function loadModel(){
	// 遍历子网格
        object.traverse(function (child) {
          if (child.isMesh) {
            // 纹理设置
            console.log("遍历子网格");
            child.material.map = texture;
          }
        });
        // 网格模型按xyz进行放缩
        object.scale.set(2, 2, 2);

        object.position.y = -65;
        object.position.x = -1045;
        object.position.z = -50;
        // 几何体绕着x轴旋转45度
        object.rotateX(Math.PI / 6);
        scene.add(object);
        // 页面加载成功后没有立即渲染模型,调用立即渲染函数
        renderScene();
}

loader.load('obj文件路径',function(obj)->{
	object=obj;
});

将loadModel传递给LoadingManager的构造函数中

// 将loadModel传递给LoadingManager的构造函数中
const manager = new THREE.LoadingManager(loadModel);

将manager作为纹理和模型加载器的构造函数中

// 将manager作为纹理和模型加载器的构造函数中

const  textureLoader = new THREE.TextureLoader(manager);

var loader =new OBJLoader(manager);

控制台查看manager是否打印,将遍历子网格的方法注释掉暂时用不到

⑥加载mtl文件

// 创建加载mtl的对象,manager作为参数传入
 var mtlLoader = new MTLLoader(manager);
// 加载mtl 文件 ,参数1: mtl文件路径 , 参数2:回调函数
 mtlLoader.load('./male02/male02.mtl',function(materials){
		// 调用预加载函数,作用: 让浏览器提前加载指定资源(加载后并不执行),在需要执行的时候再执行
		materials.preload();
		
 })

声明一个变量用于存储加载好的材质实例

 // 声明一个变量用于存储加载好的材质实例
 var mat;
  mtlLoader.load('./male02/male02.mtl',function(materials){
		// 调用预加载函数,作用: 让浏览器提前加载指定资源(加载后并不执行),在需要执行的时候再执行
		materials.preload();
		mat=materials;
 })

载入模型材质

   // 创建加载mtl的对象,manager作为参数传入
      var mtlLoader = new MTLLoader(manager);
      // 加载mtl 文件 ,参数1: mtl文件路径 , 参数2:回调函数
      mtlLoader.load("../../static/536.mtl", function (materials) {
        // 调用预加载函数,作用: 让浏览器提前加载指定资源(加载后并不执行),在需要执行的时候再执行
        materials.preload();
        mat = materials;
        // 创建objLoader对象
        var loader = new OBJLoader(manager);
        loader.setMaterials(mat);
        loader.load("../../static/536.obj", function (obj) {
          object = obj;
        },onProgress,onError);
      });

定义onproces函数用于显示模型的加载进度和加载出错函数

 // 定义onproces函数用于显示模型的加载进度
      function onProgress(xhr) {
        //做一个判断,如果获取到模型信息就控制台输出一个模型进度

        if (xhr.lengthComputable) {
          const percentComplete = (xhr.loaded / xhr.total) * 100;
          console.log(
            "model " + Math.round(percentComplete, 2) + "% downloaded"
          );
        }
      }
      // 加载出错的函数,暂不编写
      function onError() {}

作为加载obj文件回调函数的参数

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值