学习碰撞检测之前,我们先了解一下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 中的元素发生了碰撞
*
*/
var originPoint = movingCube.position.clone();
for (var vertexIndex = 0; vertexIndex < movingCube.geometry.vertices.length; vertexIndex++) {
// 顶点原始坐标
var lo