在three.js,可以利用THREE.Raycaster来达到点击与交互,即选择物体的操作。
那么我们先来认识一下THREE.Raycaster,它的构造函数如下:
new Raycaster( origin, direction, near, far );
参数介绍:
origin — 射线的起点向量。 direction — 射线的方向向量,应该归一标准化。 near — 投射近点,所有返回的结果应该比 near 远。Near不能为负,默认值为0。 far — 投射远点,所有返回的结果应该比 far 近。Far 不能小于 near,默认值为无穷大。
几个核心函数:
1、setFromCamera ( coords, camera ):
用一个新的原点和方向向量来更新射线(ray),用照相机的原点和点击的点构成一条直线。
参数:
coords — 鼠标的二维坐标,在归一化的设备坐标中,也就是X 和 Y 分量应该介于 -1 和 1 之间。
camera — 射线起点处的相机,即把射线起点设置在该相机位置处。
2、intersectObject ( object, recursive )
检查射线和物体之间的所有交叉点(包含或不包含后代)。交叉点返回按距离排序,最接近的为第一个。 返回一个交叉点对象数组。
参数:
object — 用来检测和射线相交的物体。
recursive — 如果为true,它还检查所有后代。否则只检查该对象本身。缺省值为false。
3、intersectObjects( objects, recursive ),和上面的函数功能一样,区别是这个是一个数组。
简单示例:
var raycaster = new THREE.Raycaster();
raycaster.setFromCamera( mouse, camera );//通过鼠标点的位置和当前相机的矩阵计算出raycaster
var intersects = raycaster.intersectObjects( objects );// 获取raycaster直线和所有模型相交的数组集合
//选中第一个射线相交的物体
if (intersects.length > 0) { SELECTED = intersects[0].object; var intersected = intersects[0].object; }
返回的intersected是一个数组,[ { distance, point, face, faceIndex, indices, object }, ... ]
distance – 射线的起点到相交点的距离
point – 在世界坐标中的交叉点
face – 相交的面
faceIndex – 相交的面的索引
indices – 组成相交面的顶点索引
object – 相交的对象
知识补充:
世界坐标系:在webGL中,世界坐标系是以屏幕中心为原点(0, 0, 0),且是始终不变的。你面对屏幕,你的右边是x正轴,上面是y正轴,屏幕指向你的为z正轴。长度单位这样来定:窗口范围按此单位恰好是(-1,-1)到(1,1),即屏幕左下角坐标为(-1,-1),右上角
坐标为(1,1)。
屏幕坐标系:
webGL的重要功能之一就是将三维的世界坐标经过变换、投影等计算,最终算出它在显示设备上对应的位置,这个位置就称为设备坐标。在屏幕、打印机等设备上的坐标是二维坐标。
视点坐标系:
是以视点(照相机)为原点,以视线的方向为Z+轴正方向的坐标系中的方向。webGL会将世界坐标先变换到视点坐标,然后进行裁剪,只有在视线范围(视见体)之内的场景才会进入下一阶段的计算。