vue-cli3.0以上 threejs引入obj模型 点击显示模型数据 点击高亮

先看一下 效果图

vue-cli3.0以上 threejs引入obj模型 点击显示模型数据 点击高亮_第1张图片vue-cli3.0以上 threejs引入obj模型 点击显示模型数据 点击高亮_第2张图片

vue-cli3.0以上 threejs引入obj模型 点击显示模型数据 点击高亮_第3张图片

基础知识 可以看 我之前写的 https://blog.csdn.net/www_share8/category_9385409.html

首先 说一下 可能遇到的问题,

第一个可能遇见,vue-cli3.0中没有 static 所以你的 模型可以引入不了,这个时候 你的 模型需要放到 public文件中

第二个是 引入obj模型,贴图没有显示,问题主要是更改mtl文件中图片路径,

上面的是问题  需求就是 引入模型 并点击模型 在对应的 模型 做展示

首先第一个问题,将模型放入 public中

 data () {
    return {
      baseUrl: process.env.BASE_URL
    }
}

加载模型,注意.load路径,同时注意 dealMeshMaterial 这个函数是留着 后期做高高亮的

initObject () {
      let objLoader2 = new OBJLoader2()
      let mtlLoader = new MTLLoader()
      let _this = this
      let urls_mtl = `${this.baseUrl}` + '/webgl/test.mtl'
      let urls_obj = `${this.baseUrl}` + '/webgl/test.obj'

      mtlLoader.load(urls_mtl, function (mtlParseResult) {
        console.log(mtlParseResult)
        objLoader2.setLogging(true, true)

        objLoader2.addMaterials(MtlObjBridge.addMaterialsFromMtlLoader(mtlParseResult))
        objLoader2.load(urls_obj, function (calldata) {
        _this.oldChildren = _this.dealMeshMaterial(calldata.children)
          _this.scene.add(calldata)
        }, null, null, null)
      })
    },
 /**
     * 留住每个模型的 原材质
     */
    dealMeshMaterial (arrs) {
      let result = []
      for (let i = 0; i < arrs.length; i++) {
        let obj = {
          'name': arrs[i].name,
          'material': arrs[i].material
        }
        result.push(obj)
      }
      return result
    },

其次 需要更改 .mtl文件,注意 map_ka, map_kb 这个是指定图片路径的 

将图片和 mtl文件放在同一目录下就  可以直接写 图片名字就行

vue-cli3.0以上 threejs引入obj模型 点击显示模型数据 点击高亮_第4张图片

newmtl 02___Default
	Ns 10.0000
	Ni 1.5000
	d 1.0000
	Tr 0.0000
	Tf 1.0000 1.0000 1.0000 
	illum 2
	Ka 0.5882 0.5882 0.5882
	Kd 0.5882 0.5882 0.5882
	Ks 0.0000 0.0000 0.0000
	Ke 0.0000 0.0000 0.0000
	map_Ka _auto_1.png
	map_Kd _auto_1.png

newmtl 01___Default
	Ns 10.0000
	Ni 1.5000
	d 1.0000
	Tr 0.0000
	Tf 1.0000 1.0000 1.0000 
	illum 2
	Ka 0.5882 0.5882 0.5882
	Kd 0.5882 0.5882 0.5882
	Ks 0.0000 0.0000 0.0000
	Ke 0.0000 0.0000 0.0000
	map_Ka _auto_4.png
	map_Kd _auto_4.png

至于 点击 模型展示

我是直接在 2D平面上展示的  因为项目需求 没有要求 在3D模型中展示  ,3D展示的  大家可以参考 我之前写的 这篇文章  你根据 思路 去写https://blog.csdn.net/WWW_share8/article/details/102826326

点击事件,高亮的原理是 之前先备份一份原 材质 ,在  点击之前先还原  ,最后 通过 new THREE.材质 

map 使用原来记录的  材质 map  添加一个高亮颜色就可以了

  /**
     * 点击事件
     */
    mouseClick (event) {
     // 还原之前的 点击状态
     this.restore(this.scene.children[2].children, this.oldChildren)
      // 获取 raycaster 和所有模型相交的数组,其中的元素按照距离排序,越近的越靠前
      let intersects = this.getIntersects(event)
      console.log(intersects)
      // 获取选中最近的 Mesh 对象
      if (intersects.length != 0 && intersects[0].object instanceof THREE.Mesh) {
        let selectObject = intersects[0].object;
        this.showObject(selectObject, event);
      }
    },

 restore (arrsNew, arrsOld) {
      for (let i = 0; i < arrsNew.length; i++) {
        for (let j = 0; j < arrsOld.length; j++) {
          if (arrsNew[i].name === arrsOld[j].name) {
            arrsNew[i].material = arrsOld[j].material
            break
          }
        }
      }
    },
/**
     * 展示点击内容
     */
    showObject (obj, event) {
      console.log(obj)
      let key = obj.name
      let objs = this.cabinetData.filter(item => {
        return item.code === key
      })
      // 显示内容,高亮
      if (objs.length > 0) {
        let oldOneMaterial = this.oldChildren.filter(item => item.name === key)[0]
        obj.material = new THREE.MeshPhongMaterial({
          color: 0xff0000,
          map: oldOneMaterial.material.map
        });
        this.texts = objs[0]
        // 处理坐标
        this.dragTop = event.clientY - 50
        this.dragLeft = event.clientX - 100
      } else {
        this.init()
      }
    },

将平面 坐标 转换到3D坐标

   /**
     * 将屏幕坐标转换为3d 坐标
     */
    getIntersects (event) {
      event.preventDefault();
      console.log("event.clientX:" + event.clientX)
      console.log("event.clientY:" + event.clientY)

      // 声明 raycaster 和 mouse 变量
      var raycaster = new THREE.Raycaster();
      var mouse = new THREE.Vector2();
      // 通过鼠标点击位置,计算出 raycaster 所需点的位置,以屏幕为中心点,范围 -1 到 1
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

      //通过鼠标点击的位置(二维坐标)和当前相机的矩阵计算出射线位置
      raycaster.setFromCamera(mouse, this.camera);

      // 获取与射线相交的对象数组,其中的元素按照距离排序,越近的越靠前
      var intersects = raycaster.intersectObjects(this.scene.children, true);
      //返回选中的对象
      return intersects;
    },

其次 就是  点击 事件后 需要  展示 的 内容,因为 我和做模型的同事那  了解到  他可以在mesh中 name属性 上添加 标记

所以  我只需要获取name属性 就可以了

 /**
     * 展示点击内容
     */
    showObject (obj, event) {
      console.log(obj)
      let key = obj.name
      let objs = this.cabinetData.filter(item => {
        return item.code === key
      })
      // 显示内容
      this.texts = objs[0]
      // 处理坐标
      this.dragTop = event.clientY - 50
      this.dragLeft = event.clientX - 100
    },

下面是  代码





 

你可能感兴趣的:(webGL学习,vue,threejs,three引入obj模型,three中点击事件)