点击物体
前文提到怎么在三维空间中添加物品模型,那如何知道物品被你的鼠标点击到了呢?
举一个示例:
功能
默认情况点击屏幕 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;
}
});
});