three.js利用射线Raycaster进行碰撞检测
本文实例为大家分享了利用射线Raycaster进行碰撞检测的具体代码,供大家参考,具体内容如下
学习碰撞检测之前,我们先了解一下Raycaster类
Raycaster应该翻译为“光线投射”,顾名思义,就是投射出去的一束光线。
Raycaster的构造函数如下
Raycaster(origin,direction,near,far){ origin—射线的起点向量。 direction—射线的方向向量,应该归一化。 near—所有返回的结果应该比near远。Near不能为负,默认值为0。 far—所有返回的结果应该比far近。Far不能小于near,默认值为无穷大。
使用Raycaster进行碰撞检测
用Raycaster来检测碰撞的原理很简单,我们需要以物体的中心为起点,向各个顶点(vertices)发出射线,然后检查射线是否与其它的物体相交。如果出现了相交的情况,检查最近的一个交点与射线起点间的距离,如果这个距离比射线起点至物体顶点间的距离要小,则说明发生了碰撞。
这个方法有一个 缺点,当物体的中心在另一个物体内部时,是不能够检测到碰撞的。而且当两个物体能够互相穿过,且有较大部分重合时,检测效果也不理想。
还有需要 注意的一点是:在Three.js中创建物体时,它的顶点(veritces)数目是与它的分段数目相关的,分段越多,顶点数目越多。为了检测过程中的准确度考虑,需要适当增加物体的分段。
检测光线是否与物体相交使用的是 intersectObject或 intersectObjects方法:
.intersectObject(object,recursive) //object—检测该物体是否与射线相交。 //recursive—如果设置,则会检测物体所有的子代。
相交的结果会以一个数组的形式返回,其中的元素依照距离排序,越近的排在越前.
这样通过对数组中的元素进行处理,就能得出想要的结果。
intersectObjects与 intersectObject类似,除了传入的参数是一个数组之外,并无大的差别。
/** *功能:检测movingCube是否与数组collideMeshList中的元素发生了碰撞 * */ varoriginPoint=movingCube.position.clone(); for(varvertexIndex=0;vertexIndex0&&collisionResults[0].distance 在Three.js中是使用矩阵来记录3D转换的,每一个Object3D的实例都有一个矩阵,存储了位置position,旋转rotation和伸缩scale。
varglobalVertex=localVertex.applyMatrix4(movingCube.matrix);这一句代码将物体的本地坐标乘以变换矩阵,得到了这个物体在世界坐标系中的值,处理之后的值才是我们所需要的。
下面是一个测试的完整实例:
index.html
Document