本文介绍使用.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
}