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