返回
ThreeJS光线投射(Raycaster)计算鼠标点击物体(拾取)
前端
2024-02-10 10:38:51
在三维空间中计算鼠标点击了哪个物体,其实就是从点击的那个点开始发出一条射线,看这条线穿过了哪些物体。 在此之前先来熟悉一下三维空间的坐标系,在threeJs中使用的是右手坐标系,屏幕的中心点为原点。坐标轴的正方向分别指向屏幕的右方、上方和前方。
为了使用Raycaster,首先需要创建一个Raycaster对象。这个对象可以重用,不需要每次使用时都创建新的。
const raycaster = new THREE.Raycaster();
接下来,我们需要设置射线的方向。射线的方向是通过一个原点和一个方向向量来定义的。原点是射线发出的点,方向向量是射线的方向。
const mouse = new THREE.Vector2();
const raycaster.setFromCamera( mouse, camera );
这里,mouse
是鼠标点击的屏幕坐标,camera
是当前的相机。setFromCamera()
方法会根据鼠标点击的屏幕坐标和相机的位置来计算出射线的方向。
现在,就可以使用raycaster
对象来检测射线穿过的物体了。
const intersects = raycaster.intersectObjects( scene.children, true );
intersectObjects()
方法会返回一个数组,其中包含了射线穿过的所有物体。每个元素都是一个Intersection
对象,包含了射线与物体的交点信息。
通过遍历intersects
数组,就可以获取到鼠标点击的物体。
if ( intersects.length > 0 ) {
const object = intersects[ 0 ].object;
}
还可以使用Raycaster
来检测射线是否与物体相交,而不需要返回交点信息。
const intersects = raycaster.intersectObjects( scene.children, true );
if ( intersects.length > 0 ) {
// 射线与物体相交
} else {
// 射线没有与物体相交
}
示例
以下是一个示例,展示了如何使用Raycaster
来计算鼠标点击了哪个物体。
<!DOCTYPE html>
<html>
<head>
<script src="three.js"></script>
</head>
<body>
<canvas id="myCanvas"></canvas>
<script>
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.z = 5;
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
// 创建一个立方体
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
// 创建一个射线投射器
const raycaster = new THREE.Raycaster();
// 监听鼠标点击事件
window.addEventListener( 'click', ( event ) => {
// 获取鼠标点击的屏幕坐标
const mouse = new THREE.Vector2();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
// 设置射线的方向
raycaster.setFromCamera( mouse, camera );
// 检测射线与物体的交点
const intersects = raycaster.intersectObjects( scene.children, true );
if ( intersects.length > 0 ) {
// 射线与物体相交
// 获取鼠标点击的物体
const object = intersects[ 0 ].object;
// 改变物体的颜色
object.material.color.set( 0xff0000 );
}
} );
// 渲染场景
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
animate();
</script>
</body>
</html>
在上面的示例中,当鼠标点击屏幕时,射线投射器会计算出射线的方向。然后,射线投射器会检测射线与场景中物体的交点。如果射线与物体相交,则会改变物体的颜色。
总结
Raycaster
类是一个强大的工具,可以用来检测射线与物体的交点。这可以用于拾取物体、进行交互操作等。希望本文能帮助你了解Raycaster
类的用法。