threejs 点击隐藏模型显示模型下的子模型

threejs yekong

3d可视化案例 厂房开发时,客户又有新的需求要求点击特定模型隐藏模型显示模型下的子模型
一开始是点击后进行高亮显示,如图是点击后显示为蓝色,现在有两个地方下面是有子模型的,所以要求点击后模型隐藏以便于显示子模型

处理前

处理前

处理后

上面的模型隐藏,显示出下面的子模型。点击其他模型后,重新恢复上面的模型显示。
上面的模型隐藏,显示出下面的子模型

关键代码处理

主要

选中处理

根据射线拾取的模型进行判断,如果模型名称中包含我们的特定模型名称,则对模型进行隐藏处理 如果模型上有css2D资源则对css2D资源进行隐藏处理。

if (child.isMesh) {
    child.material.color.set(0x00ffff)
    if (chooseMesh.name.includes('智能立库') || chooseMesh.name.includes('包装车间')) {
      child.material.visible = false
    }
    if (chooseMesh.name.includes('包装车间')) {
      for (var i = 0; i < 21; i++) {
        console.log(document.getElementById('jizhan' + (i + 1)))
        console.log('jizhan' + (i + 1))
        document.getElementById('jizhan' + (i + 1)).style.visibility = 'hidden'
        // visible
      }
    }
}

不选中后处理

//css2d资源恢复显示
for (var i = 0; i < 21; i++) {
    document.getElementById('jizhan' + (i + 1)).style.visibility = 'visible'
  }
//模型恢复显示
chooseMesh.material.visible = true

choose完整代码

// 引入three.js
import * as THREE from 'three/build/three.module.js'
import { camera } from './RendererCamera.js'
import { granaryArr, granaryArr2 } from './scene/model.js'//获取所有粮仓模型对象的集合
import { model } from './scene/model.js'
// 鼠标单击射线拾取meshArr中的某个粮仓Mesh
var chooseMesh = null

function choose (event, messageTag) {
  for (var i = 0; i < 21; i++) {
    document.getElementById('jizhan' + (i + 1)).style.visibility = 'visible'
    // visible
  }
  if (chooseMesh) {
    // 把上次选中的mesh设置为原来的颜色
    granaryArr2.forEach((type) => {
      if (chooseMesh.name.includes(type.title)) {
        chooseMesh.material.color.set(type.color)
        chooseMesh.material.visible = true
        model.children.forEach((type2) => {
          var models = type2.getObjectByName(type.title)
          if (models) {
            models.traverse(function (child) {
              if (child.isMesh) {
                child.material.color.set(type.color)
                child.material.visible = true
              }
            })
          }
        })
      }
      if (chooseMesh.name === type.title) {
        chooseMesh.material.color.set(type.color)
      }
    })
    // label.element.style.visibility = 'hidden';//隐藏标签
  }
  var Sx = event.offsetX //鼠标单击位置横坐标
  var Sy = event.offsetY //鼠标单击位置纵坐标
  //屏幕坐标转WebGL标准设备坐标
  var x = (Sx / window.innerWidth) * 2 - 1 //WebGL标准设备横坐标
  var y = -(Sy / window.innerHeight) * 2 + 1 //WebGL标准设备纵坐标
  //创建一个射线投射器`Raycaster`
  var raycaster = new THREE.Raycaster()
  //通过鼠标单击位置标准设备坐标和相机参数计算射线投射器`Raycaster`的射线属性.ray
  raycaster.setFromCamera(new THREE.Vector2(x, y), camera)
  //返回.intersectObjects()参数中射线选中的网格模型对象
  // 未选中对象返回空数组[],选中一个数组1个元素,选中两个数组两个元素
  var intersects = raycaster.intersectObjects(granaryArr)
  // console.log("射线器返回的对象", intersects);
  // console.log("射线投射器返回的对象 点point", intersects[0].point);
  // console.log("射线投射器的对象 几何体",intersects[0].object.geometry.vertices)
  // intersects.length大于0说明,说明选中了模型
  if (intersects.length > 0) {
    chooseMesh = intersects[0].object
    chooseMesh.material.color.set(0x00ffff)
    chooseMesh.point = intersects[0].point
    granaryArr2.forEach((type) => {
      if (chooseMesh.name.includes(type.title)) {
        model.children.forEach((type2) => {
          console.log(type2.getObjectByName(type.title))
          var models = type2.getObjectByName(type.title)
          console.log(models)
          if (models) {
            models.traverse(function (child) {
              if (child.isMesh) {
                child.material.color.set(0x00ffff)
                if (chooseMesh.name.includes('智能立库') || chooseMesh.name.includes('包装车间')) {
                  child.material.visible = false
                }
                if (chooseMesh.name.includes('包装车间')) {
                  for (var i = 0; i < 21; i++) {
                    console.log(document.getElementById('jizhan' + (i + 1)))
                    console.log('jizhan' + (i + 1))
                    document.getElementById('jizhan' + (i + 1)).style.visibility = 'hidden'
                    // visible
                  }
                }
              }
            })
          }
        })
      }
    })
  } else {
    chooseMesh = null
  }
}

// addEventListener('click', choose); // 监听窗口鼠标单击事件,鼠标单击选中某个国家Mesh
// addEventListener('mousemove', choose);//鼠标滑动事件

export { choose, chooseMesh }

喜欢