threejs 3d模型 射线拾取实例 group处理

js yekong

threejs 3d模型 射线拾取实例 group处理

要求

threejs 要求模型被选中后高亮并且显示名称,但是这里的模型是由多个网格模型组成的group,需要在选择做处理

演示地址

3d可视化案例 厂房

实现

将事先配置好的名称加入数组,遍历当前射线拾取的模型名称是否包含在实现配置的数组中,是的话则获取分组名称并遍历,将当前分组内的模型修改颜色。

// 引入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) {
  if (chooseMesh) {
    // 把上次选中的mesh设置为原来的颜色
    granaryArr2.forEach((type) => {
      if (chooseMesh.name.includes(type.title)) {
        chooseMesh.material.color.set(type.color)
        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)
              }
            })
          }
        })
      }
      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 / 1900) * 2 - 1 //WebGL标准设备横坐标
  var y = -(Sy / 822) * 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)
              }
            })
          }
        })
      }
    })
  } else {
    chooseMesh = null
  }
}
export { choose, chooseMesh }

喜欢