提示:本系列文章参考http://www.webgl3d.cn/Three.js/的three.js教程。
前言
本篇主要介绍光线投射Raycaster用于进行鼠标拾取,形成鼠标点击事件的效果。
一、光线投射Raycaster
想要给物体添加点击事件,官方文档提供了一个Raycast类进行物体拾取。这个类用于进行raycasting(光线投射), 光线投射用于进行鼠标拾取(在三维空间中计算出鼠标移过了什么物体)。
1.返回物体和射线的焦点
原理:
先创建了Raycaster对象,通过setFromCamera函数像场景物体发出射线,再通过intersectObject检测射线投射到的物体。
var raycaster = new THREE.Raycaster();
var mouseVector = new THREE.Vector2();
function getIntersects(x, y) {
//将鼠标位置转换成设备坐标。x和y方向的取值范围是(-1 to 1)
x = (x / width) * 2 - 1;
y = -(y / height) * 2 + 1;
mouseVector.set(x, y);
//通过摄像机和鼠标位置更新射线
raycaster.setFromCamera(mouseVector, camera);
// 返回物体和射线的焦点
return raycaster.intersectObject(mesh2, true);
}
函数解释:
setFromCamera ( coords, camera ) 中。
coords — 鼠标的二维坐标,在归一化的设备坐标(NDC)中,也就是X 和 Y 分量应该介于 -1 和 1 之间。
camera — 射线起点处的相机,即把射线起点设置在该相机位置处。 用一个新的原点和方向向量来更新射线(ray)。
intersectObject ( object, recursive )
object — 用来检测和射线相交的物体。
recursive — 如果为true,它还检查所有后代。否则只检查该对象本身。缺省值为false。
2.设置侦听事件
window.addEventListener("click", onDocumentMouseMove, false);
addEventListener是一个侦听事件并处理相应的函数,
(事件的类型type:String,
侦听到事件后处理事件的函数listener:Function,
useCapture:Boolean = false, true,则侦听器只在捕获阶段处理事件,而不在目标或冒泡阶段处理事件。 如果useCapture 为 false,则侦听器只在目标或冒泡阶段处理事件。 要在所有三个阶段都侦听事件,请调用两次 addEventListener,一次将 useCapture 设置为 true,第二次再将useCapture 设置为 false
priority:int = 0, 事件侦听器的优先级。数字越大,优先级越高,默认为零
useWeakReference:Boolean = false 确定对侦听器的引用是强引用,还是弱引用。 强引用(默认值)可防止您的侦听器被当作垃圾回收。 弱引用则没有此作用。)
3.侦听到事件后处理响应的函数
onDocumentMouseMove()函数
var selectObject = null;
function onDocumentMouseMove(event) {
//用 event.stopPropagation()阻止事件的传递行为
//用preventDefault()的方法来阻止元素的默认行为,比如超链接单击后需要跳转的默认行为
event.preventDefault();
if (selectObject) {
console.log(selectObject);
selectObject.material.color.set(0x0000ff);
selectObject = null;
}
var intersects = getIntersects(event.layerX, event.layerY);
if (intersects.length > 0) {
var res = intersects.filter(function(res) {
return res && res.object
})[0];
if (res && res.object) {
//console.log(res)
alert("触发点击事件,物体变绿,点击别的地方恢复颜色");
selectObject = res.object;
selectObject.material.color.set(0x00ff00);
//window.location.href = "test111.html";
}
}
}