three.js 之 Raycaster 光线投射

2023-03-06 15 three.js

介绍

光线投射Raycaster选中物体进行交互实现

# 什么是光线投射

# 场景子对象scene.children的光线投射

光线投射器可以投射scene.children中的场景所包含的所有物体(子对象)

// 创建二维向量 用于记录鼠标的位置
const mouse = new THREE.Vector2()
window.addEventListener('mousemove', ({ clientX, clientY }) => { // mousemove 鼠标移动事件 还可以替换其他时间click等
  // 将鼠标点击位置的屏幕坐标转换成three.js中的标准设备坐标
  mouse.x = (clientX / window.innerWidth) * 2 - 1 // X轴坐标 2个单位 -1到1
  mouse.y = -((clientY / window.innerHeight) * 2 - 1) // Y轴坐标 2个单位 -1到1 这里需要反转一下 因为在JS/CSS坐标中Y轴是反的

  // 创建一个光线投射器
  const raycaster = new THREE.Raycaster()
  // 设置光线投射器的射线 通过setFromCamera()设置 传入鼠标的位置和相机
  raycaster.setFromCamera(mouse, this.camera)

  // 投射scene场景中含的所有物体(子对象)
  const cube = raycaster.intersectObjects(this.scene.children) // 会返回所有与射线相交的多个对象的数组
  
  // 遍历选中的立方体 批量修改
  cube.forEach((item) => {
    console.log(item.object)
    // 替换所选材质 item.object是Object3D类型 需要断言为Mesh类型
    // ;(item.object as THREE.Mesh).material = this.redMaterial
  })
})

复制代码

# 多个/ 单个物体的Object3D数组集合

.intersectObjects (opens new window) 默认的参数是不支持单个Object3D类型的, 但是它支持投射数组的方式Object3D类型集合, 比如: [Object3D1, Object3D2], 这样他就能通过投射检测这两个Object3D类型的物体只要其中之一投射到就返回投射信息

.intersectObject (opens new window) 检查与射线相交的单个物体。需要单个物体的Object3D数组集合

// 创建一个光线投射器
const raycaster = new THREE.Raycaster()
// 投射多个Object3D对象, 以数组的形式
const spriteMeshRay = raycaster.intersectObjects([
  this.spriteMesh,
  this.iphone,
]) // 规定只要投射到这两个物体(其中之一), 就返回投射的信息

// 单个Object3D对象, 使用.intersectObject方法
const cube = raycaster.intersectObject(this.iphone) 

// Object3D数组集合可以直接使用.intersectObjects
const spriteMeshRay = raycaster.intersectObjects(this.spriteMeshList)

复制代码
Last Updated: 2023/3/24 10:17:53
来发评论吧~
Powered By Valine
v1.4.14
未加载音频 - (ಗ ‸ ಗ )
00:00 / 00:00