燕飞7 2023-05-16 14:31 采纳率: 0%
浏览 96
已结题

threejs 加载碰撞环境后,之前点击事件不起作用

加载碰撞器环境loadCollider后,之前正常工作的opendoor点击不起作用了。而且通过日志发现这个门点击区域有了偏转

img

img

    loadCollider(model) { 
      const that = this
      const gltfScene = model // 模型
      this.box3d = new THREE.Box3() // 表示三维空间中的一个轴对齐包围盒
      that.box3d.setFromObject(model) // 计算和世界轴对齐的一个对象 Object3D(含其子对象)的包围盒
      gltfScene.updateMatrixWorld(true) //更新物体及其后代的全局变换。

      const toMerge = {} // 合并组合
      gltfScene.traverse(c => {
        if (c.isMesh && c.material.color !== undefined) {
          // 根据颜色将所有模型分类
          const MeshBVH = c.material.color.getHex()
          toMerge[MeshBVH] = toMerge[MeshBVH] || []
          toMerge[MeshBVH].push(c)
        }
      })

      // 环境 :创建一个组合
      that.environment = new THREE.Group()
      for (const hex in toMerge) {
        const arr = toMerge[hex] // 获得同一个颜色的模型数组
        arr.forEach(mesh => {
          that.environment.attach(mesh) // 将mesh作为子级来添加到该对象中,同时保持该object的世界变换。
        })
      }

      that.geometries = [] //视觉几何数组
      that.environment.updateMatrixWorld(true) //更新模型世界坐标
      that.environment.traverse(c => {
        if (c.geometry) {

          // if (c.name === 'Plane056') {
          //   that.id = c.id
          //   console.log(c.id, 'cid')
          // }
          const cloned = c.geometry.clone()  //克隆几何结构
          cloned.applyMatrix4(c.matrixWorld) // 对当前物体应用这个变换矩阵,并更新物体的位置、旋转和缩放。
          // 移除位置外的其他属性
          for (const key in cloned.attributes) {
            if (key !== 'position') {
              cloned.deleteAttribute(key)
            }
          }

          that.geometries.push(cloned) //添加到视觉几何数组
        }
      })

      that.mergedGeometry = mergeBufferGeometries(that.geometries, false)
      that.mergedGeometry.boundsTree = new MeshBVH(that.mergedGeometry, {
        lazyGeneration: false
      }) //生成 BVH 并使用新生成的索引
      that.collider = new THREE.Mesh(that.mergedGeometry)// 生成网格
      that.visualizer = new MeshBVHVisualizer(that.collider, that.params.visualizeDepth) // 网格bvh可视化工具()
      // that.visualizer.layers.set(that.currentlayers)
      that.scene.add(that.visualizer) //可视化工具
      that.scene.add(that.environment) // 环境
      that.scene.add(model)
    },

getIntersects(event, group) {
      event.preventDefault()// 阻止默认的点击事件执行,   
      let rayCaster = new THREE.Raycaster()
      let mouse = new THREE.Vector2()
      //通过鼠标点击位置,计算出raycaster所需点的位置,以屏幕为中心点,范围-1到1;event.clientX鼠标点击位置
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1 //  这里为什么是-号,没有就无法点中

      //通过鼠标点击的位置(二维坐标)和当前相机的矩阵计算出射线位置
      rayCaster.setFromCamera(mouse, this.camera)
      let intersects = rayCaster.intersectObjects([group], true)
      return intersects
    },
    // 打开门
    opendoor(event) {
      // let arr = null
      for (const k in this.doors) {
        if (this.doors[k].group && this.camera) {
          const result = this.getIntersects(event, this.doors[k].group)
          if (result.length > 0) {
            this.open_door(k)
          }
        }
      }
    },
    open_door(index) {
      console.log("index:" + index);
      const { isclose, axis, group, rotation, rotate_deg } = this.doors[index]
      group.rotation[axis] = isclose ? rotation + rotate_deg : rotation
      this.doors[index].isclose = !isclose
    }
  • 写回答

4条回答 默认 最新

  • 阳光宅男xxb 2023-05-23 08:02
    关注
    获得7.50元问题酬金

    检查下控制台日志,看看是否有与碰撞器环境或点击门相关的错误消息。如果有,请找到错误消息并确定是哪个脚本或代码导致的。或者重新加载场景模型看看。

    评论

报告相同问题?

问题事件

  • 系统已结题 5月24日
  • 创建了问题 5月16日