Skip to main content

点击物体

前文提到怎么在三维空间中添加物品模型,那如何知道物品被你的鼠标点击到了呢?

举一个示例:

功能

默认情况点击屏幕 Five 会执行游走或模态切换,示例的要求是在空间中添加一个正方体,当点击到正方体时则提示 "恭喜,你点到物体啦" 且不执行默认行为。

添加物体

在模型加载成功后,再在空间中添加立方体。

five.once("modelLoaded", () => {
five.setState({ mode: "Floorplan" });

const geometry = new THREE.BoxGeometry(1, 1, 1, 32);
const material = new THREE.MeshBasicMaterial({color: new THREE.Color(0x2008aa)});
const box = new THREE.Mesh(geometry, material);
box.position.set(-2.8741698071921214, 0.220446049250313, -4.631508324407246);
five.scene.add(box);

five.on("wantsTapGesture", (raycaster, tapPosition) => {
// 回调中手势尚未触发,可以执行碰撞逻辑
const intersect = raycaster.intersectObject(box);
console.log("intersect", intersect);

const [clickedMesh] = intersect;
if (clickedMesh) {
alert("恭喜,你点击物体啦");
return false;
}
});
});

点击事件

监听 five.on('wantsTapGesture') 意向点击手势的事件。

five.once("modelLoaded", () => {
five.setState({ mode: "Floorplan" });

const geometry = new THREE.BoxGeometry(1, 1, 1, 32);
const material = new THREE.MeshBasicMaterial({color: new THREE.Color(0x2008aa)});
const box = new THREE.Mesh(geometry, material);
box.position.set(-2.8741698071921214, 0.220446049250313, -4.631508324407246);
five.scene.add(box);
five.on("wantsTapGesture", (raycaster) => {
// 监测逻辑
});

});

计算交点

"wantsTapGesture" 回调函数中自带光线投射 Raycaster 实例,你可以基于 Raycaster 计算当前相机到点击位置组成的射线和物体的交点。

five.once("modelLoaded", () => {
five.setState({ mode: "Floorplan" });

const geometry = new THREE.BoxGeometry(1, 1, 1, 32);
const material = new THREE.MeshBasicMaterial({color: new THREE.Color(0x2008aa)});
const box = new THREE.Mesh(geometry, material);
box.position.set(-2.8741698071921214, 0.220446049250313, -4.631508324407246);
five.scene.add(box);

five.on("wantsTapGesture", (raycaster, tapPosition) => {
// 回调中手势尚未触发,可以执行碰撞逻辑
const intersect = raycaster.intersectObject(box);
});
});

判断结果

计算的结果 intersect 是个数组,表明射线与物体相交的个数,直接判断返回值情况即可了解物体是否被点击到。

five.once("modelLoaded", () => {
five.setState({ mode: "Floorplan" });

const geometry = new THREE.BoxGeometry(1, 1, 1, 32);
const material = new THREE.MeshBasicMaterial({color: new THREE.Color(0x2008aa)});
const box = new THREE.Mesh(geometry, material);
box.position.set(-2.8741698071921214, 0.220446049250313, -4.631508324407246);
five.scene.add(box);

five.on("wantsTapGesture", (raycaster, tapPosition) => {
// 回调中手势尚未触发,可以执行碰撞逻辑
const intersect = raycaster.intersectObject(box);

const [clickedMesh] = intersect;
if (clickedMesh) {
alert("恭喜,你点到物体啦");
// 点击到 正方体,终止事件
return false;
}
});
});