先前想做个3D人物移动场景,那就必然会遇到碰撞检测的问题,那么今天就来浅谈一下Three.js的碰撞检测。
规则几何体
球体
在规则几何体,球体的碰撞检测是最好处理的,只要判断两点圆心之间的距离是否小于两球体半径之和便可判断是否发生碰撞。
1 2 3 4
| function isCrashed() { var dist = sphereL.position.clone().distanceTo(sphereR.position.clone()); return dist < 10; }
|
效果如下:
矩形
如果矩形像球体一样处理,判断会不太精确。
如下图:
所幸,Three.js提供了一种方法让我们来进行碰撞检测,那既是射线(Raycaster)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| function isCrashed() { var originPoint = sphereR.position.clone(); for(var vertexIndex = 0; vertexIndex < sphereR.geometry.vertices.length; vertexIndex++){ var localVertex = sphereR.geometry.vertices[vertexIndex].clone(); var globaVertex = localVertex.applyMatrix4(sphereR.matrix); var directionVector = globaVertex.sub(sphereR.position); var ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize()); var collisionResults = ray.intersectObjects([sphereL]); if(collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() + 1.2 ){ return true } } return false }
|
效果如下:
从效果可以看出,第二种方法会比第一种方法精确很多。
不规则几何体
对于不规则几何体,还是宜用射线,选取任意数量的顶点,以中心至顶点做射线,射线越密则越精确,但是效率却越低,为了提高运行效率,可只对运动的物体在其运动方向做射线,以此来判断物理是否碰撞上物体,而不必判断物体是否被碰撞,以此可提高一倍以上的性能。