Threejs实现手动拖拽剖切

演示效果

threejs版本116

实现过程

1、利用box3获取模型边界

const box3 = new Box3();
box3.setFromObject(this.clipingModel); // 获取模型对象的边界
this.low = box3.min;
this.high = box3.max;
this.low_init.copy(this.low); // 保留一下初始值,好作为限制条件
this.high_init.copy(this.high);
this.group = new Group();

2、初始化剖切盒的 6 个剖切平面

    private initPlanes() {
        this.planes = [];
        this.planes.push(
            new Plane(new Vector3(0, -1, 0), this.high.y), // 上
            new Plane(new Vector3(0, 1, 0), -this.low.y), // 下
            new Plane(new Vector3(1, 0, 0), -this.low.x), // 左
            new Plane(new Vector3(-1, 0, 0), this.high.x), // 右
            new Plane(new Vector3(0, 0, -1), this.high.z), // 前
            new Plane(new Vector3(0, 0, 1), -this.low.z), // 后
        );
        this.clipingModel.traverse((child: any) => {
            if (['Mesh', 'LineSegments'].includes(child.type)) {
                child.material.clippingPlanes = this.planes;
            }
        });
    }

3、初始化剖切盒的顶点

        this.vertices[0].set(this.low.x, this.high.y, this.low.z);
        this.vertices[1].set(this.high.x, this.high.y, this.low.z);
        this.vertices[2].set(this.high.x, this.high.y, this.high.z);
        this.vertices[3].set(this.low.x, this.high.y, this.high.z);
        this.vertices[4].set(this.low.x, this.low.y, this.low.z);
        this.vertices[5].set(this.high.x, this.low.y, this.low.z);
        this.vertices[6].set(this.high.x, this.low.y, this.high.z);
        this.vertices[7].set(this.low.x, this.low.y, this.high.z);

4、定义拖拽面

    initFaces() {
        this.faces = [
            new ClipFace('y2', [0, 1, 2, 3].map(i => ({ dirty: true, position: this.vertices![i] }))),// x+
            new ClipFace('y1', [4, 7, 6, 5].map(i => ({ dirty: true, position: this.vertices![i] }))), // x-
            new ClipFace('x1', [0, 3, 7, 4].map(i => ({ dirty: true, position: this.vertices![i] }))),// y+
            new ClipFace('x2', [1, 5, 6, 2].map(i => ({ dirty: true, position: this.vertices![i] }))),// y-
            new ClipFace('z2', [2, 6, 7, 3].map(i => ({ dirty: true, position: this.vertices![i] }))), // z-
            new ClipFace('z1', [0, 4, 5, 1].map(i => ({ dirty: true, position: this.vertices![i] }))), // z+
        ]
        this.faces.forEach(face => {
            this.group.add(face)
        })
    }

5、定义边线

    private initLines() {

        this.lines = [
            new ClipLine([0, 1].map(i => ({ dirty: true, position: this.vertices![i] }))),// positive left 0
            new ClipLine([1, 2].map(i => ({ dirty: true, position: this.vertices![i] }))),// positive top  1
            new ClipLine([2, 3].map(i => ({ dirty: true, position: this.vertices![i] }))),// positive right 2
            new ClipLine([3, 0].map(i => ({ dirty: true, position: this.vertices![i] }))),// positive bottom 3

            new ClipLine([4, 5].map(i => ({ dirty: true, position: this.vertices![i] }))),// negative left 4
            new ClipLine([5, 6].map(i => ({ dirty: true, position: this.vertices![i] }))),// negative top 5
            new ClipLine([6, 7].map(i => ({ dirty: true, position: this.vertices![i] }))),// negative right 6
            new ClipLine([7, 4].map(i => ({ dirty: true, position: this.vertices![i] }))),// negative bottom 7

            new ClipLine([1, 5].map(i => ({ dirty: true, position: this.vertices![i] }))),// left top 8
            new ClipLine([0, 4].map(i => ({ dirty: true, position: this.vertices![i] }))),// left bottom 9


            new ClipLine([2, 6].map(i => ({ dirty: true, position: this.vertices![i] }))),// right top 10
            new ClipLine([3, 7].map(i => ({ dirty: true, position: this.vertices![i] }))),// right bottom 11
        ]
        this.faces![0].lines = [0, 1, 2, 3].map(d => this.lines![d])    //y2
        this.faces![1].lines = [4, 5, 6, 7].map(d => this.lines![d])    //y1
        this.faces![2].lines = [3, 7, 9, 11].map(d => this.lines![d])   //x1
        this.faces![3].lines = [1, 5, 8, 10].map(d => this.lines![d])   //x2
        this.faces![4].lines = [2, 6, 10, 11].map(d => this.lines![d])  //z2
        this.faces![5].lines = [0, 4, 8, 9].map(d => this.lines![d])   //z1
        this.lines.forEach(line => {
            this.group.add(line)
        })
    }

鼠标操作则为拖拽面后相应修改对应的剖切面,实现手动拖拽剖切

感兴趣的评论留言吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值