WebGL教程_Three.js教程_郭隆邦技术博客 郭隆邦_技术博客 一对一班

Three.js射线碰撞检测

下面代码是通过threejs射线计算的方法来计算两个网格模型是否发生了碰撞,下面代码用到的threejs类比较多,能顺序阅读下面代码,需要对threejs向量Vector3、矩阵Matrix4、射线Ray和射线投射器Raycaster有一定的理解。

//检测球体sphereMesh网格模型是否和立方体网格模型boxMesh发生了碰撞,也就是两个模型是否是相互交叉状态

//设置球体位于不同位置,用来测试碰撞
sphereMesh.position.x = 40; //两个网格模型不交叉
sphereMesh.position.x = 25; //两个网格模型相互交叉
//声明一个变量用来表示是否碰撞
var bool = false;
// threejs的几何体默认情况下几何中心在场景中坐标是坐标原点。
// 可以通过position属性或.getWorldPosition()方法获得模型几何中心的世界坐标
var centerCoord = sphereMesh.position.clone();
//球体网格模型几何体的所有顶点数据
var vertices = sphereMesh.geometry.vertices

//1.循环遍历球体几何体所有顶点坐标
//2.把几何体的每一个顶点和几何体中心构建一个射线
//3.
for (var i = 0; i < vertices.length; i++) {
  // vertices[i]获得几何体索引是i的顶点坐标,
  // 注意执行.clone()返回一个新的向量,以免改变几何体顶点坐标值
  // 几何体的顶点坐标要执行该几何体绑定模型对象经过的旋转平移缩放变换
  // 几何体顶点经过的变换可以通过模型的本地矩阵属性.matrix或世界矩阵属性.matrixWorld获得
  var vertexWorldCoord = vertices[i].clone().applyMatrix4(sphereMesh.matrixWorld);

  var dir = new THREE.Vector3(); //创建一个向量
  // 几何体顶点坐标和几何体中心坐标构成的方向向量
  dir.subVectors(vertexWorldCoord, centerCoord);


  //Raycaster构造函数创建一个射线投射器对象,参数1、参数2改变的是该对象的射线属性.ray
  // 参数1:射线的起点
  // 参数2:射线的方向,注意归一化的时候,需要先克隆,否则后面会执行dir.length()计算向量长度结果是1
  var raycaster = new THREE.Raycaster(centerCoord, dir.clone().normalize());


  // 计算射线和参数1中的模型对象是否相交,参数1数组中可以设置多个模型模型对象,下面参数只设置了立方体网格模型
  var intersects = raycaster.intersectObjects([boxMesh]);
  if (intersects.length > 0) { // 判断参数[boxMesh]中模型对象是否与射线相交
    // intersects[0].distance:射线起点与交叉点之间的距离(交叉点:射线和模型表面交叉点坐标)
    // dir.length():球体顶点和球体几何中心构成向量的长度
    // 通过距离大小比较判断是否碰撞
    // intersects[0].distance小于dir.length(),说明交叉点的位置在射线起点和球体几何体顶点之间,
    //而交叉点又在立方体表面上,也就是说立方体部分表面插入到了球体里面
    if (intersects[0].distance < dir.length()) {
      //循环遍历几何体顶点,每一个顶点都要创建一个射线,进行一次交叉拾取计算,只要有一个满足上面的距离条件,就发生了碰撞
      bool = true;
    }
  }
}
//在浏览器控制显示当前两个模型对象是否碰撞(也就是相互交叉状态)
if (bool) {
  console.log('碰撞');
} else {
  console.log('未碰撞');
}

计算量

通过上面的代码你可以看到,如果要判断一个网格模型和另一个网格模型是否碰撞,需要循环遍历该模型绑定几何体Geometry的所有顶点位置坐标,然后分别创建一个射线,然后把创建的射线与其它网格模型进行射线拾取交叉计算,这也就是说该模型几何体的顶点数量阅读,计算量越大。

准确度

threejs碰撞检测是通过几何体的顶点来判断,也就是说几何体细分数越大,顶点数多,计算越准确,但是计算量会比较大。

本站版权所有,本站任何内容未经允许不得转载   备案号:豫ICP备16004767号 QQ群:187740169 (WebGL-Three.js教程)   邮箱:guolongbang@163.com