Threejs 物体碰撞检测

 

本文介绍使用.Raycaste()方案实现物体碰撞检测

origin — 光线投射的原点向量。
direction — 射线的方向向量,应该归一化。
near — 所有返回的结果应该比 near 远。near不能为负,默认值为0。
far — 所有返回的结果应该比 far 近。far 不能小于 near,默认值为无穷大。
Raycaster(origin, direction, near, far)

检测思路 

两个物体 A B

获取物体A的坐标中心

获取物体A上每个顶点坐标到A中心的距离R

由A的中心向A的所有网格顶点发射射线,射线起点是A中心,方向是A—>every point

发射射线,若射线有相交,获取相交点的distance(交点到A中心坐标的距离)

判断distance如果小于R,则说明两个物体相交

如下代码

  function onIntersect() {
    // 声明一个变量用来表示是否碰撞
    let bool = false

    // .position 对象局部位置
    // .clone() 复制一个新的三维向量
    // 网格中心 世界坐标
    const centerCoord = cube.position.clone()
    // 获取网格中 几何对象的顶点对象
    const position = cube.geometry.attributes.position
    // 顶点三维向量
    const vertices = []
    // .count 矢量个数
    for (let i = 0; i < position.count; i++) {
      // .getX() 获取给定索引的矢量的第一维元素
      vertices.push(new THREE.Vector3(position.getX(i), position.getY(i), position.getZ(i)))
    }

    for (let i = 0; i < vertices.length; i++) {
      // .matrixWorld 物体的世界坐标变换 -- 物体旋转、位移 的四维矩阵
      // .applyMatrix4() 将该向量乘以四阶矩阵
      // 获取世界坐标下 网格变换后的坐标
      let vertexWorldCoord = vertices[i].clone().applyMatrix4(cube.matrixWorld)

      // .sub(x) 从该向量减去x向量
      // 获得由中心指向顶点的向量
      var dir = vertexWorldCoord.clone().sub(centerCoord)

      // .normalize() 将该向量转换为单位向量
      // 发射光线 centerCoord 为投射的原点向量  dir 向射线提供方向的方向向量
      let raycaster = new THREE.Raycaster(centerCoord, dir.clone().normalize())

      // 放入要检测的 物体cube2,返回相交物体
      let intersects = raycaster.intersectObjects([cube2], true)

      if (intersects.length > 0) {
        // intersects[0].distance:射线起点与交叉点之间的距离(交叉点:射线和模型表面交叉点坐标)
        // dir.length():几何体顶点和几何体中心构成向量的长度
        // intersects[0].distance小于dir.length() 表示物体相交
        if (intersects[0].distance < dir.length()) {
          bool = true
        }
      }
    }
    return bool
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山楂树の

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值