Vue+Three.js 入门四(鼠标点击模型实现交互)

LZQ plus

发布于 2020.02.29 13:49 阅读 6054 评论 0

实现点击模型触发事件的思路

    在一个3D场景中,事件的交互大部分是点击鼠标完成的,像上图显示的那样,我点击了3号车间,然后与其对应的生产数据框就显示出来了。那么“它”是怎么知道我点击的就是3号车间,这里就用到Three里的一个构造函数“光线投射Raycaster”,Raycaster里的一个方法“setFromCamera”就是从我们场景里的Camera的坐标向我们鼠标点击的方向(这个方向是从2D向3D计算过的,公式统一)发出一条射线,从而获取到这条射线所穿过的模型数组,进而获取到具体是哪个模型(数组里的第一个)。这里可能有疑问,我怎么知道获取到的模型就是3号车间并于3号车间的生产数据关联起来的?我的思路就是导入模型时,将唯一识别字段放进模型数据里面去,我用的是“name”字段,然后Raycaster获取到模型数据在对比一下“name”就获取到了3号车间的生产数据。

实现点击模型触发事件的代码实施

因为我用的是Vue框架,所以就用Vue的格式顺序介绍。

首先是data里面存放两个对象:

        //用于点击事件

        raycaster: new THREE.Raycaster(),

        mouse: new THREE.Vector2(),

然后methods里向容器添加点击监听事件:

        this.container.addEventListener('click', this.onMouseClick, false);

然后methods里针对监听事件编写具体逻辑:

      onMouseClick(event) {

        this.dialogControl = {

          show: false,

          top: 0,

          left: 0

        };

        // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)

        this.mouse.x = (event.clientX / this.container.clientWidth) * 2 - 1;

        this.mouse.y = -(event.clientY / this.container.clientHeight) * 2 + 1;

        this.raycaster.setFromCamera(this.mouse, this.camera);



        // 计算物体和射线的焦点

        let intersects = this.raycaster.intersectObjects(this.scene.children, true);

        // 获取选中最近的 Mesh 对象

        if (intersects.length !== 0 && intersects[0].object instanceof THREE.Mesh) {

          let selectName = intersects[0].object.name;

          this.houseData.forEach(h => {

            if (h.id === selectName) {

              this.dialogData = h;

              this.dialogControl = {

                show: true,

                top: event.clientY,

                left: event.clientX

              };

            }

          });

        }

      },

完成以上代码就完成了交互,其中上文中的houseData、dialogData、dialogControl是我自己代码里的需求,可以不做参考。