<template>
    <div>
        <div id="containerThreeSensorModel"></div>
    </div>
</template>

<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { ConvexGeometry } from "three/examples/jsm/geometries/ConvexGeometry.js";
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader.js";
import { MTLLoader } from "three/examples/jsm/loaders/MTLLoader.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
// import * as BufferGeometryUtils from "three/examples/jsm/utils/BufferGeometryUtils.js";
import { BufferGeometryUtils } from "three/examples/jsm/utils/BufferGeometryUtils.js";
import { mapState } from "vuex";

// "three": "^0.142.0"
const ThreeBSP = require('three-js-csg')(THREE)
// import ThreeBSP from "../common/ThreeCSG";

// import { ThreeBSP } from "../common/ThreeBSP";


// import { ADDITION, SUBTRACTION, INTERSECTION, DIFFERENCE, Brush, Evaluator } from 'three-bvh-csg';

import {
    showFullScreenLoading,
    tryHideFullScreenLoading,
} from "../../../axios/filter";

export default {
    name: "threeSensorModel", // 传感器配置中的threeJS
    components: {},

    data() {
        return {
            publicPath: process.env.BASE_URL,
            scene: null,
            camera: null,
            renderer: null,
            light: null,
            transformControls: null,
            geometryName: "cube",
            controls: null,
            mesh: null,
            cube: null,
            cacheList: [],
            container: null,
            car: null,
            cubeTexture: null,
            raf: null,
            canDrag: true, // 是否可移动
            dragControls: null,
            sensor: null, // 当前操作的传感器配置
            cameraSensor: null,
            ogt: null,
            lidar: null,
            gps: null,
            // scale: 2, // 物体加载换算倍数
            group1: null,
            group2: null,
            r: 15,
            r1: 6,
            horizontal: 300,
            vertical: 360,
            horizontalL: 180,
            horizontalR: 120,
            verticalT: 75,
            verticalB: 150,
            a1: null,
            b1: null,
            c1: null,
            d1: null,
            a2: null,
            b2: null,
            c2: null,
            d2: null,
            e1: null,
            x1: null,
            y1: null,
            z1: null,
            v1: null,
            w1: null,
            x2: null,
            y2: null,
            z2: null,
            v2: null,
            w2: null,
        };
    },

    computed: {
        ...mapState(["scale"]),
    },

    props: {
        coordinate: {
            type: Object,
            default: { f: 0, n: 0, h: 0, v: 0 },
        },
        coordinateA: {
            type: Object,
            default: { f: 0, n: 0, hl: 0, hr: 0, vt: 0, vb: 0 },
        },
        type: {
            type: Number,
            default: 1,
        },
    },

    methods: {
        // 场景
        initScene() {
            this.scene = new THREE.Scene();
            let axes = new THREE.AxesHelper(12000);
            this.scene.add(axes);

            const gridHelper = new THREE.GridHelper(21000, 2100);
            gridHelper.material.opacity = 0.25;
            gridHelper.material.transparent = true;
            this.scene.add(gridHelper);
        },
        // 相机
        initCamera() {
            this.camera = new THREE.PerspectiveCamera(
                75,
                this.container.clientWidth / this.container.clientHeight,
                0.1,
                30000
            );

            this.camera.position.set(200, 200, 200);
            this.scene.add(this.camera);
        },
        // 渲染器
        initRenderer() {
            this.renderer = new THREE.WebGLRenderer({
                antialias: true,
                alpha: true,
            });
            this.renderer.setSize(
                this.container.clientWidth,
                this.container.clientHeight
            );
            this.renderer.setClearColor("#272727");
            this.container.appendChild(this.renderer.domElement);
        },
        // 初始化灯光
        initLight() {
            var hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444);
            hemiLight.position.set(0, 20, 0);
            this.scene.add(hemiLight);

            // 环境光会均匀的照亮场景中的所有物体
            const light = new THREE.AmbientLight(0x5c5c5c, 0.4); // soft white light
            this.scene.add(light);

            // 平行光是沿着特定方向发射的光
            const dirLight = new THREE.DirectionalLight(0xffffff, 0.5);
            this.scene.add(dirLight);
        },
        // 初始化模型
        initContent() {
            const obj = this.scene.getObjectByName("cube");
            if (obj) {
                this.scene.remove(obj);
                this.clearCache(obj);
            }

            const sensor = this.scene.getObjectByName("sensor");
            if (sensor) {
                this.scene.remove(sensor);
                this.clearCache(sensor);
            }

            /* if (this.type === 1) {
                if (this.cameraSensor) {
                    this.scene.add(this.cameraSensor);
                } else {
                    this.initSensor({ x: 0, y: 0, z: 0 }, "camera");
                }
            } else if (this.type === 2) {
                if (this.ogt) {
                    this.scene.add(this.ogt);
                } else {
                    this.initSensor({ x: 0, y: 0, z: 0 }, "ogt");
                }
            } else if (this.type === 3) {
                if (this.lidar) {
                    this.scene.add(this.lidar);
                } else {
                    this.initSensor({ x: 0, y: 0, z: 0 }, "lidar");
                }
            } else if (this.type === 4) {
                if (this.gps) {
                    this.scene.add(this.gps);
                } else {
                    this.initSensor({ x: 0, y: 0, z: 0 }, "gps");
                }
            } */

            if (this.type != 2) {
                let r = this.coordinate.f;
                let r1 = this.coordinate.n;

                if (r <= 0 || r1 < 0 || r <= r1) {
                    return;
                }

                this.initSenA(r * this.scale, r1 * this.scale);
            } else {
                let r = this.coordinateA.f;
                let r1 = this.coordinateA.n;

                if (r <= 0 || r1 < 0 || r <= r1) {
                    return;
                }

                this.initSenB(r * this.scale, r1 * this.scale);
            }
        },
        // 处理轴对称物体
        initSenA(r, r1) {
            let x = 0,
                y = 0,
                z = r;

            let a = this.coordinate.h,
                b = this.coordinate.v;

            if (a >= 90) a = 89.99;
            if (b >= 90) b = 89.99;

            // x = Math.tan(THREE.MathUtils.degToRad(a)) * r;
            // y = Math.tan(THREE.MathUtils.degToRad(b)) * r;

            let pointsArr = [];

            if (r1 === 0) {
                pointsArr = [
                    [0, 0, 0],
                    [x, y, z],
                    [x, -y, z],
                    [-x, -y, z],
                    [-x, y, z],
                ];
            } else {
                let x1 = 0,
                    y1 = 0,
                    z1 = r1;

                // x1 = Math.tan(THREE.MathUtils.degToRad(a)) * r1;
                // y1 = Math.tan(THREE.MathUtils.degToRad(b)) * r1;

                pointsArr = [
                    [x1, y1, z1],
                    [x1, -y1, z1],
                    [-x1, -y1, z1],
                    [-x1, y1, z1],
                    [x, y, z],
                    [x, -y, z],
                    [-x, -y, z],
                    [-x, y, z],
                ];
            }

            this.initMesh(pointsArr);
        },
        // 处理非轴对称物体
        initSenB(r, r1) {
            let x1 = 0,
                x2 = 0,
                y1 = 0,
                y2 = 0,
                z1 = r;

            let a = this.coordinateA.hl,
                b = this.coordinateA.vt,
                c = this.coordinateA.hr,
                d = this.coordinateA.vb;

            if (a >= 90) a = 89.99;
            if (b >= 90) b = 89.99;
            if (c >= 90) c = 89.99;
            if (d >= 90) d = 89.99;

            // x1 = Math.tan(THREE.MathUtils.degToRad(a)) * r;
            // y1 = Math.tan(THREE.MathUtils.degToRad(b)) * r;
            // x2 = Math.tan(THREE.MathUtils.degToRad(c)) * r;
            // y2 = Math.tan(THREE.MathUtils.degToRad(d)) * r;

            let pointsArr = [];

            if (r1 === 0) {
                pointsArr = [
                    [0, 0, 0],
                    [x1, y1, z1],
                    [x1, -y2, z1],
                    [-x2, -y2, z1],
                    [-x2, y1, z1],
                ];
            } else {
                let m1 = 0,
                    m2 = 0,
                    n1 = 0,
                    n2 = 0,
                    z2 = r1;

                // m1 = Math.tan(THREE.MathUtils.degToRad(a)) * r1;
                // n1 = Math.tan(THREE.MathUtils.degToRad(b)) * r1;
                // m2 = Math.tan(THREE.MathUtils.degToRad(c)) * r1;
                // n2 = Math.tan(THREE.MathUtils.degToRad(d)) * r1;

                pointsArr = [
                    [m1, n1, z2],
                    [m1, -n2, z2],
                    [-m2, -n2, z2],
                    [-m2, n1, z2],
                    [x1, y1, z1],
                    [x1, -y2, z1],
                    [-x2, -y2, z1],
                    [-x2, y1, z1],
                ];
            }

            this.initMesh(pointsArr);
        },
        initDemo() {
            let horizontal = this.horizontal;

            let phiStart = Math.PI * ((90 - horizontal) / 180),
                phiLength = Math.PI * (horizontal * 2 / 180),
                thetaStart = Math.PI * 0,
                thetaLength = Math.PI * 1;

            const geometry = new THREE.SphereGeometry(
                15, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });




            const sphere = new THREE.Mesh(geometry, material);
            // sphere.rotateY(Math.PI * -0.25);
            // this.scene.add(sphere);



            const geometry1 = new THREE.CircleGeometry(
                15, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material1 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle1 = new THREE.Mesh(geometry1, material1);
            circle1.rotateZ(Math.PI * -0.5);
            circle1.rotateX(phiStart);
            // this.scene.add(circle1); // left



            const geometry2 = new THREE.CircleGeometry(
                15, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material2 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle2 = new THREE.Mesh(geometry2, material2);
            circle2.rotateZ(Math.PI * 0.5);
            circle2.rotateX(phiStart);
            // this.scene.add(circle2); // right

            const group = new THREE.Group();
            group.add(sphere);
            group.add(circle1);
            group.add(circle2);

            group.translateZ(40);

            this.scene.add(group);
        },
        initDemo1() {
            let vertical = this.vertical;

            let phiStart = Math.PI * ((90 - vertical) / 180),
                phiLength = Math.PI * (vertical * 2 / 180),
                thetaStart = Math.PI * 0,
                thetaLength = Math.PI * 1;

            const geometry = new THREE.SphereGeometry(
                15, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });
            const sphere = new THREE.Mesh(geometry, material);
            sphere.rotateZ(Math.PI * 0.5);
            // this.scene.add(sphere);



            const geometry1 = new THREE.CircleGeometry(
                15, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material1 = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });
            const circle1 = new THREE.Mesh(geometry1, material1);
            // circle1.rotateZ(Math.PI * -0.5);
            circle1.rotateX(phiStart);
            // this.scene.add(circle1); // top



            const geometry2 = new THREE.CircleGeometry(
                15, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material2 = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });
            const circle2 = new THREE.Mesh(geometry2, material2);
            // circle2.rotateY(Math.PI * 0.5);
            circle2.rotateX(-phiStart - Math.PI);
            // this.scene.add(circle2); // bottom



            const group = new THREE.Group();
            group.add(sphere);
            group.add(circle1);
            group.add(circle2);

            group.translateZ(40);

            this.scene.add(group);
        },
        initOgtDemo() {
            let horizontal = this.horizontalR;

            let phiStart = Math.PI * ((90 - horizontal) / 180),
                phiLength = Math.PI * (horizontal / 180),
                thetaStart = Math.PI * 0,
                thetaLength = Math.PI * 1;

            // phiStart = 0;

            const geometry = new THREE.SphereGeometry(
                15, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });

            const sphere = new THREE.Mesh(geometry, material);
            // sphere.rotateY(phiStart);
            // this.scene.add(sphere); // 右





            let horizontal0 = this.horizontalL;

            let phiStart0 = Math.PI * (90 / 180),
                phiLength0 = Math.PI * (horizontal0 / 180),
                thetaStart0 = Math.PI * 0,
                thetaLength0 = Math.PI * 1;

            // phiStart = 0;

            const geometry0 = new THREE.SphereGeometry(
                15, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart0, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength0, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength0 // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material0 = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });

            const sphere0 = new THREE.Mesh(geometry0, material0);
            // sphere.rotateY(phiStart);
            // this.scene.add(sphere0); // 左



            const geometry1 = new THREE.CircleGeometry(
                15, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material1 = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });
            const circle1 = new THREE.Mesh(geometry1, material1);
            circle1.rotateZ(Math.PI * -0.5);
            circle1.rotateX(Math.PI * ((90 - horizontal0) / 180));
            // this.scene.add(circle1); // left



            const geometry2 = new THREE.CircleGeometry(
                15, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material2 = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });
            const circle2 = new THREE.Mesh(geometry2, material2);
            circle2.rotateZ(Math.PI * 0.5);
            circle2.rotateX(phiStart);
            // this.scene.add(circle2); // right


            const group = new THREE.Group();
            group.add(sphere);
            group.add(circle1);
            group.add(circle2);
            group.add(sphere0);

            group.translateZ(40);

            this.scene.add(group);
        },
        initOgtDemo1() {
            let vertical = this.verticalB;

            let phiStart = Math.PI * ((90 - vertical) / 180),
                phiLength = Math.PI * (vertical / 180),
                thetaStart = Math.PI * 0,
                thetaLength = Math.PI * 1;

            const geometry = new THREE.SphereGeometry(
                15, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const sphere = new THREE.Mesh(geometry, material);
            sphere.rotateZ(Math.PI * 0.5);
            // this.scene.add(sphere); // 下





            let vertical0 = this.verticalT;

            let phiStart0 = Math.PI * (90 / 180),
                phiLength0 = Math.PI * (vertical0 / 180),
                thetaStart0 = Math.PI * 0,
                thetaLength0 = Math.PI * 1;

            const geometry0 = new THREE.SphereGeometry(
                15, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart0, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength0, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength0 // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material0 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const sphere0 = new THREE.Mesh(geometry0, material0);
            sphere0.rotateZ(Math.PI * 0.5);
            // this.scene.add(sphere0); // 上



            const geometry1 = new THREE.CircleGeometry(
                15, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material1 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle1 = new THREE.Mesh(geometry1, material1);
            circle1.rotateX(Math.PI * ((90 - vertical0) / 180));
            // circle1.rotateZ(0);
            // this.scene.add(circle1); // top



            const geometry2 = new THREE.CircleGeometry(
                15, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material2 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle2 = new THREE.Mesh(geometry2, material2);
            // let p = -phiStart - Math.PI;
            circle2.rotateX(-phiStart - Math.PI);
            // circle2.rotateZ(0);
            // this.scene.add(circle2); // bottom

            const group = new THREE.Group();
            group.add(sphere);
            group.add(circle1);
            group.add(circle2);
            group.add(sphere0);

            group.translateZ(40);

            this.scene.add(group);

        },
        initLeft() {
            let horizontal = this.horizontal / 2;

            if (horizontal % 90 === 0) horizontal = horizontal - 0.1;

            let phiStart = Math.PI * ((90 - horizontal) / 180),
                phiLength = Math.PI * (horizontal * 2 / 180),
                thetaStart = Math.PI * 0,
                thetaLength = Math.PI * 1;

            const geometry = new THREE.SphereGeometry(
                this.r, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });




            const sphere = new THREE.Mesh(geometry, material);
            // sphere.rotateY(Math.PI * -0.25);
            // this.scene.add(sphere);



            const geometry1 = new THREE.CircleGeometry(
                this.r, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material1 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle1 = new THREE.Mesh(geometry1, material1);
            circle1.rotateZ(Math.PI * -0.5);
            circle1.rotateX(phiStart);
            // this.scene.add(circle1); // left

            const geometry11 = new THREE.CircleGeometry(
                this.r, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                Math.PI * 0.75, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1.5 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material11 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle11 = new THREE.Mesh(geometry11, material11);
            circle11.rotateZ(Math.PI * -0.5);
            circle11.rotateX(phiStart);
            // circle11.rotateX(Math.PI * 0.5);





            const geometry2 = new THREE.CircleGeometry(
                this.r, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material2 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle2 = new THREE.Mesh(geometry2, material2);
            circle2.rotateZ(Math.PI * 0.5);
            circle2.rotateX(phiStart);
            // this.scene.add(circle2); // right

            const geometry22 = new THREE.CircleGeometry(
                this.r, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                Math.PI * 0.75, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1.5 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material22 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle22 = new THREE.Mesh(geometry22, material22);
            circle22.rotateZ(Math.PI * 0.5);
            circle22.rotateX(phiStart);


            /* const group = new THREE.Group();
            group.add(sphere);
            group.add(circle1);
            group.add(circle2); */

            // this.scene.add(group);

            /* const geometry6 = new THREE.BoxGeometry(1, 1, 1);
            const material6 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle6 = new THREE.Mesh(geometry6, material6); */

            // let geometryArray = [geometry, geometry1, geometry2]; // 将你的要合并的多个geometry放入到该数组
            // let materialArray = [material]; // 将你的要赋值的多个material放入到该数组
            // 合并模型
            //  geometry.attributes = {
            //     faceVertexUvs: geometry.faceVertexUvs,
            //     faces: geometry.faces,
            //  }
            //  geometry.morphAttributes = {
            //     faceVertexUvs: geometry.faceVertexUvs,
            //     faces: geometry.faces,
            //  }

            //  console.log(geometry);
            // console.log(geometry.attributes);
            // console.log(geometry instanceof THREE.BufferGeometry);
            // console.log(geometry.getAttribute());
            // console.log(material);
            // console.log(BufferGeometryUtils.mergeBufferGeometries);
            // console.log(BufferGeometryUtils);
            //  const mergedGeometries = BufferGeometryUtils.mergeBufferGeometries(geometryArray);
            // console.log(mergedGeometries);
            //  const singleMergeMesh = new THREE.Mesh(mergedGeometries, materialArray);

            // this.scene.add(singleMergeMesh);



            /* const geometry9 = BufferGeometryUtils.mergeBufferGeometries([
                new THREE.BoxGeometry(2, 1, 1),
                new THREE.CylinderGeometry(1, 1, 1, 10),
            ]);

            console.log(geometry);
            const mergedMesh = new THREE.Mesh(geometry9, material);

            mergedMesh.position.y = -1;
            // scene.add(car, mergedMesh); */


            // sphere.add(circle1);
            // sphere.add(circle2);


            // this.group1 = new ThreeBSP(sphere);
            // this.group1 = new ThreeBSP(singleMergeMesh);



            // intersect （交集） union （并集） subtract （差集）

            this.a1 = new ThreeBSP(sphere);
            this.b1 = new ThreeBSP(circle1);
            // this.b1 = new ThreeBSP(circle11);
            this.c1 = new ThreeBSP(circle2);
            // this.c1 = new ThreeBSP(circle22);



            let h = Math.sin(THREE.MathUtils.degToRad(this.vertical)) * this.r,
                r1 = Math.cos(THREE.MathUtils.degToRad(this.vertical)) * this.r;

            const cone1 = new THREE.ConeGeometry(
                r1, // radius — 圆锥底部的半径，默认值为1
                h, // height — 圆锥的高度，默认值为1
                32, // radialSegments — 圆锥侧面周围的分段数，默认为32
                1, // heightSegments — 圆锥侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                2 * Math.PI, // thetaLength — 圆锥底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆锥
            );

            cone1.translate(0, -h / 2, 0);
            cone1.rotateX(Math.PI * 1);

            const cone2 = new THREE.ConeGeometry(
                r1, // radius — 圆锥底部的半径，默认值为1
                h, // height — 圆锥的高度，默认值为1
                32, // radialSegments — 圆锥侧面周围的分段数，默认为32
                1, // heightSegments — 圆锥侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                2 * Math.PI, // thetaLength — 圆锥底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆锥
            );
            cone2.translate(0, -h / 2, 0);



            const circle01 = new THREE.CircleGeometry(h * 0.1, 32);
            circle01.rotateX(Math.PI * 0.5);
            circle01.translate(0, h, 0);

            const circle02 = new THREE.CircleGeometry(h * 0.1, 32);
            circle02.rotateX(Math.PI * 0.5);
            circle02.translate(0, -h, 0);


            this.x1 = new ThreeBSP(circle01); // up
            this.y1 = new ThreeBSP(cone1);
            this.x2 = new ThreeBSP(circle02); // down
            this.y2 = new ThreeBSP(cone2);

            const sphere1 = new THREE.SphereGeometry(
                15, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                0, // phiStart — 指定水平（经线）起始角度，默认值为0
                Math.PI * 2, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                Math.PI // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            this.z1 = new ThreeBSP(sphere1);



            /*  var m = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });
             // const resultBSP = a.subtract(b);
             const resultBSP = a.subtract(b).subtract(c).toMesh(m);
             // this.group1 = new ThreeBSP(sphere);
             console.log(resultBSP);
             this.scene.add(resultBSP); */



            /* const evaluator = new Evaluator();
            let a = new Brush(geometry, material);
            a.updateMatrixWorld();
            let b = new Brush(geometry1, material1);
            b.rotateZ(Math.PI * -0.5);
            b.rotateX(phiStart);
            b.updateMatrixWorld();
            let c = new Brush(geometry2, material2);
            c.rotateZ(Math.PI * 0.5);
            c.rotateX(phiStart);
            c.updateMatrixWorld();

            let result;
            result = evaluator.evaluate(a, b, ADDITION);
            result = evaluator.evaluate(result, c, ADDITION);

            console.log(result); */

            // this.scene.add(result);


            // this.group1 = new Brush(geometry, material);
            // this.group1 = result;
            // this.group1 = new ThreeBSP(result.geometry);
        },
        initTop() {
            let vertical = this.vertical / 2;

            if (vertical % 90 === 0) vertical = vertical - 0.1;

            let phiStart = Math.PI * ((90 - vertical) / 180),
                phiLength = Math.PI * (vertical * 2 / 180),
                thetaStart = Math.PI * 0,
                thetaLength = Math.PI * 1;

            const geometry = new THREE.SphereGeometry(
                this.r, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });
            const sphere = new THREE.Mesh(geometry, material);
            sphere.rotateZ(Math.PI * 0.5);
            // this.scene.add(sphere);



            const geometry1 = new THREE.CircleGeometry(
                this.r, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material1 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle1 = new THREE.Mesh(geometry1, material1);
            circle1.rotateX(phiStart);
            // circle1.rotateZ(0);
            // this.scene.add(circle1); // top



            const geometry2 = new THREE.CircleGeometry(
                this.r, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material2 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle2 = new THREE.Mesh(geometry2, material2);
            // let p = -phiStart - Math.PI;
            circle2.rotateX(-phiStart - Math.PI);
            // circle2.rotateZ(0);
            // this.scene.add(circle2); // bottom



            /* const group = new THREE.Group();
            group.add(sphere);
            group.add(circle1);
            group.add(circle2); */

            // this.scene.add(group);


            /* let geometryArray = [geometry, geometry1, geometry2]; // 将你的要合并的多个geometry放入到该数组
            let materialArray = [material]; // 将你的要赋值的多个material放入到该数组
            const mergedGeometries = BufferGeometryUtils.mergeBufferGeometries(geometryArray);
            const singleMergeMesh = new THREE.Mesh(mergedGeometries, materialArray); */

            // sphere.add(circle1);
            // sphere.add(circle2);


            // this.group2 = new ThreeBSP(singleMergeMesh);
            // this.group2 = new ThreeBSP(sphere);

            /* this.a1 = new ThreeBSP(sphere);
            this.b1 = new ThreeBSP(circle1);
            this.c1 = new ThreeBSP(circle2); */


            this.a2 = new ThreeBSP(sphere);
            this.b2 = new ThreeBSP(circle1);
            this.c2 = new ThreeBSP(circle2);




            let h = Math.sin(THREE.MathUtils.degToRad(this.horizontal)) * this.r,
                r1 = Math.cos(THREE.MathUtils.degToRad(this.horizontal)) * this.r;

            const cone1 = new THREE.ConeGeometry(
                r1, // radius — 圆锥底部的半径，默认值为1
                h, // height — 圆锥的高度，默认值为1
                32, // radialSegments — 圆锥侧面周围的分段数，默认为32
                1, // heightSegments — 圆锥侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                2 * Math.PI, // thetaLength — 圆锥底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆锥
            );

            cone1.translate(0, -h / 2, 0);
            cone1.rotateX(Math.PI * 1);
            cone1.rotateZ(Math.PI * 0.5);

            const cone2 = new THREE.ConeGeometry(
                r1, // radius — 圆锥底部的半径，默认值为1
                h, // height — 圆锥的高度，默认值为1
                32, // radialSegments — 圆锥侧面周围的分段数，默认为32
                1, // heightSegments — 圆锥侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                2 * Math.PI, // thetaLength — 圆锥底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆锥
            );
            cone2.translate(0, -h / 2, 0);
            cone2.rotateZ(Math.PI * 0.5);



            const circle01 = new THREE.CircleGeometry(h * 0.1, 32);
            circle01.rotateX(Math.PI * 0.5);
            circle01.translate(0, h, 0);
            circle01.rotateZ(Math.PI * 0.5);

            const circle02 = new THREE.CircleGeometry(h * 0.1, 32);
            circle02.rotateX(Math.PI * 0.5);
            circle02.translate(0, -h, 0);
            circle02.rotateZ(Math.PI * 0.5);


            this.x1 = new ThreeBSP(circle01); // left
            this.y1 = new ThreeBSP(cone1);
            this.x2 = new ThreeBSP(circle02); // right
            this.y2 = new ThreeBSP(cone2);

            const sphere1 = new THREE.SphereGeometry(
                15, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                0, // phiStart — 指定水平（经线）起始角度，默认值为0
                Math.PI * 2, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                Math.PI // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            this.z1 = new ThreeBSP(sphere1);






            /* const evaluator = new Evaluator();
                let a = new Brush(geometry, material);
                a.rotateZ(Math.PI * 0.5);
                a.updateMatrixWorld();
                let b = new Brush(geometry1, material1);
                b.rotateX(phiStart);
                b.updateMatrixWorld();
                let c = new Brush(geometry2, material2);
                c.rotateX(-phiStart - Math.PI);
                c.updateMatrixWorld();

                let result;
                result = evaluator.evaluate(a, c, SUBTRACTION);
                result = evaluator.evaluate(result, b, ADDITION);

                this.scene.add(result);
                */



            // this.group2 = new Brush(geometry, material);
            // this.group2 = result;
            // this.group2 = new ThreeBSP(result.geometry);
        },
        initLeft1() {
            let horizontal = this.horizontal;

            if (horizontal % 90 === 0) horizontal = horizontal - 0.1;

            let phiStart = Math.PI * ((90 - horizontal) / 180),
                phiLength = Math.PI * (horizontal * 2 / 180),
                thetaStart = Math.PI * 0,
                thetaLength = Math.PI * 1;

            const geometry = new THREE.SphereGeometry(
                this.r1, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });

            const sphere = new THREE.Mesh(geometry, material);




            const geometry1 = new THREE.CircleGeometry(
                this.r1, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material1 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle1 = new THREE.Mesh(geometry1, material1);
            circle1.rotateZ(Math.PI * -0.5);
            circle1.rotateX(phiStart);



            const geometry2 = new THREE.CircleGeometry(
                this.r1, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material2 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle2 = new THREE.Mesh(geometry2, material2);
            circle2.rotateZ(Math.PI * 0.5);
            circle2.rotateX(phiStart);




            this.x1 = new ThreeBSP(sphere);
            this.y1 = new ThreeBSP(circle1);
            this.z1 = new ThreeBSP(circle2);

        },
        initTop1() {
            let vertical = this.vertical;

            if (vertical % 90 === 0) vertical = vertical - 0.1;

            let phiStart = Math.PI * ((90 - vertical) / 180),
                phiLength = Math.PI * (vertical * 2 / 180),
                thetaStart = Math.PI * 0,
                thetaLength = Math.PI * 1;

            const geometry = new THREE.SphereGeometry(
                this.r1, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });
            const sphere = new THREE.Mesh(geometry, material);
            sphere.rotateZ(Math.PI * 0.5);



            const geometry1 = new THREE.CircleGeometry(
                this.r1, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material1 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle1 = new THREE.Mesh(geometry1, material1);
            circle1.rotateX(phiStart);



            const geometry2 = new THREE.CircleGeometry(
                this.r1, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material2 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle2 = new THREE.Mesh(geometry2, material2);
            let p = -phiStart - Math.PI;
            circle2.rotateX(p);




            this.x2 = new ThreeBSP(sphere);
            this.y2 = new ThreeBSP(circle1);
            this.z2 = new ThreeBSP(circle2);
        },
        initOgt() {
            let horizontal = this.horizontalR;
            let r = this.r;

            if ((horizontal + this.horizontalL) % 180 === 0) horizontal = horizontal - 0.1;

            let phiStart = Math.PI * ((90 - horizontal) / 180),
                phiLength = Math.PI * (horizontal / 180),
                thetaStart = Math.PI * 0,
                thetaLength = Math.PI * 1;

            // phiStart = 0;

            const geometry = new THREE.SphereGeometry(
                r, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });

            const sphere = new THREE.Mesh(geometry, material);
            // sphere.rotateY(phiStart);
            // this.scene.add(sphere); // 右





            let horizontal0 = this.horizontalL;

            let phiStart0 = Math.PI * (90 / 180),
                phiLength0 = Math.PI * (horizontal0 / 180),
                thetaStart0 = Math.PI * 0,
                thetaLength0 = Math.PI * 1;

            // phiStart = 0;

            const geometry0 = new THREE.SphereGeometry(
                r, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart0, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength0, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength0 // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material0 = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });

            const sphere0 = new THREE.Mesh(geometry0, material0);
            // sphere.rotateY(phiStart);
            // this.scene.add(sphere0); // 左



            const geometry1 = new THREE.CircleGeometry(
                r, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material1 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle1 = new THREE.Mesh(geometry1, material1);
            circle1.rotateZ(Math.PI * -0.5);
            circle1.rotateX(Math.PI * ((90 - horizontal0) / 180));
            // this.scene.add(circle1); // left



            const geometry2 = new THREE.CircleGeometry(
                r, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material2 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle2 = new THREE.Mesh(geometry2, material2);
            circle2.rotateZ(Math.PI * 0.5);
            circle2.rotateX(phiStart);
            // this.scene.add(circle2); // right



            const circle3 = new THREE.Mesh(geometry1, material1);
            circle3.rotateZ(Math.PI * -0.5);
            circle3.rotateX(Math.PI * 0.5);



            this.a1 = new ThreeBSP(sphere);
            this.b1 = new ThreeBSP(circle1);
            this.c1 = new ThreeBSP(circle2);
            this.d1 = new ThreeBSP(sphere0);

            this.e1 = new ThreeBSP(circle3);
        },
        initOgt1() {
            let vertical = this.verticalB;
            let r = this.r;

            // if ((vertical + this.verticalT) % 180 === 0) vertical = vertical - 0.1;

            let phiStart = Math.PI * ((90 - vertical) / 180),
                phiLength = Math.PI * (vertical / 180),
                thetaStart = Math.PI * 0,
                thetaLength = Math.PI * 1;

            const geometry = new THREE.SphereGeometry(
                r, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });
            const sphere = new THREE.Mesh(geometry, material);
            sphere.rotateZ(Math.PI * 0.5);
            // this.scene.add(sphere); // 下





            let vertical0 = this.verticalT;

            let phiStart0 = Math.PI * (90 / 180),
                phiLength0 = Math.PI * (vertical0 / 180),
                thetaStart0 = Math.PI * 0,
                thetaLength0 = Math.PI * 1;

            const geometry0 = new THREE.SphereGeometry(
                r, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart0, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength0, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength0 // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material0 = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });
            const sphere0 = new THREE.Mesh(geometry0, material0);
            sphere0.rotateZ(Math.PI * 0.5);
            // this.scene.add(sphere0); // 上



            const geometry1 = new THREE.CircleGeometry(
                r, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material1 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle1 = new THREE.Mesh(geometry1, material1);
            circle1.rotateX(Math.PI * ((90 - vertical0) / 180));
            // circle1.rotateZ(0);
            // this.scene.add(circle1); // top



            const geometry2 = new THREE.CircleGeometry(
                r, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material2 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle2 = new THREE.Mesh(geometry2, material2);
            // let p = -phiStart - Math.PI;
            circle2.rotateX(-phiStart - Math.PI);
            // circle2.rotateZ(0);
            // this.scene.add(circle2); // bottom



            this.a2 = new ThreeBSP(sphere0);
            this.b2 = new ThreeBSP(circle1);
            this.c2 = new ThreeBSP(circle2);
            this.d2 = new ThreeBSP(sphere);

            if (vertical0 + vertical >= 360) {
                const sphere1 = new THREE.SphereGeometry(
                    r, // radius — 球体半径，默认为1
                    32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                    16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                    0, // phiStart — 指定水平（经线）起始角度，默认值为0
                    Math.PI * 2, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                    0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                    Math.PI // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
                );

                this.a2 = new ThreeBSP(sphere1);
            }
        },
        initOgt0() {
            let horizontal = this.horizontalR;

            if ((horizontal + this.horizontalL) % 90 === 0) horizontal = horizontal - 0.1;

            let phiStart = Math.PI * ((90 - horizontal) / 180),
                phiLength = Math.PI * (horizontal / 180),
                thetaStart = Math.PI * 0,
                thetaLength = Math.PI * 1;

            // phiStart = 0;

            const geometry = new THREE.SphereGeometry(
                6, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });

            const sphere = new THREE.Mesh(geometry, material);
            // sphere.rotateY(phiStart);
            // this.scene.add(sphere); // 右





            let horizontal0 = this.horizontalL;

            let phiStart0 = Math.PI * (90 / 180),
                phiLength0 = Math.PI * (horizontal0 / 180),
                thetaStart0 = Math.PI * 0,
                thetaLength0 = Math.PI * 1;

            // phiStart = 0;

            const geometry0 = new THREE.SphereGeometry(
                6, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart0, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength0, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength0 // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material0 = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });

            const sphere0 = new THREE.Mesh(geometry0, material0);
            // sphere.rotateY(phiStart);
            // this.scene.add(sphere0); // 左



            const geometry1 = new THREE.CircleGeometry(
                6, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material1 = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });
            const circle1 = new THREE.Mesh(geometry1, material1);
            circle1.rotateZ(Math.PI * -0.5);
            circle1.rotateX(Math.PI * ((90 - horizontal0) / 180));
            // this.scene.add(circle1); // left



            const geometry2 = new THREE.CircleGeometry(
                6, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material2 = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });
            const circle2 = new THREE.Mesh(geometry2, material2);
            circle2.rotateZ(Math.PI * 0.5);
            circle2.rotateX(phiStart);
            // this.scene.add(circle2); // right



            this.x1 = new ThreeBSP(sphere);
            this.y1 = new ThreeBSP(circle1);
            this.z1 = new ThreeBSP(circle2);
            this.w1 = new ThreeBSP(sphere0);
        },
        initOgt01() {
            let vertical = this.verticalB;

            if ((vertical + this.verticalT) % 90 === 0) vertical = vertical - 0.1;

            let phiStart = Math.PI * ((90 - vertical) / 180),
                phiLength = Math.PI * (vertical / 180),
                thetaStart = Math.PI * 0,
                thetaLength = Math.PI * 1;

            const geometry = new THREE.SphereGeometry(
                6, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const sphere = new THREE.Mesh(geometry, material);
            sphere.rotateZ(Math.PI * 0.5);
            // this.scene.add(sphere); // 下





            let vertical0 = this.verticalT;

            let phiStart0 = Math.PI * (90 / 180),
                phiLength0 = Math.PI * (vertical0 / 180),
                thetaStart0 = Math.PI * 0,
                thetaLength0 = Math.PI * 1;

            const geometry0 = new THREE.SphereGeometry(
                6, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart0, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength0, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength0 // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material0 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const sphere0 = new THREE.Mesh(geometry0, material0);
            sphere0.rotateZ(Math.PI * 0.5);
            // this.scene.add(sphere0); // 上



            const geometry1 = new THREE.CircleGeometry(
                6, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material1 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle1 = new THREE.Mesh(geometry1, material1);
            circle1.rotateX(Math.PI * ((90 - vertical0) / 180));
            // circle1.rotateZ(0);
            // this.scene.add(circle1); // top



            const geometry2 = new THREE.CircleGeometry(
                6, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material2 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle2 = new THREE.Mesh(geometry2, material2);
            // let p = -phiStart - Math.PI;
            circle2.rotateX(-phiStart - Math.PI);
            // circle2.rotateZ(0);
            // this.scene.add(circle2); // bottom




            this.x2 = new ThreeBSP(sphere);
            this.y2 = new ThreeBSP(circle1);
            this.z2 = new ThreeBSP(circle2);
            this.w2 = new ThreeBSP(sphere0);
        },
        init1Ogt0() {
            const cylinder = new THREE.CylinderGeometry(
                20, // radiusTop — 圆柱的顶部半径，默认值是1
                20, // radiusBottom — 圆柱的底部半径，默认值是1
                16, // height — 圆柱的高度，默认值是1
                32, // radialSegments — 圆柱侧面周围的分段数，默认为32
                1, // heightSegments — 圆柱侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                2 * Math.PI, // thetaLength — 圆柱底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆柱
            );

            // cylinder.rotateY(Math.PI * -0.75);

            const material1 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide, transparent: true, opacity: 0.3, });
            const material = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide, transparent: true, opacity: 0.3, });
            const cylinderMesh = new THREE.Mesh(cylinder, material1);
            // this.scene.add(cylinderMesh);

            const cylinder1 = new THREE.CylinderGeometry(
                20, // radiusTop — 圆柱的顶部半径，默认值是1
                20, // radiusBottom — 圆柱的底部半径，默认值是1
                16, // height — 圆柱的高度，默认值是1
                32, // radialSegments — 圆柱侧面周围的分段数，默认为32
                1, // heightSegments — 圆柱侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                0.5 * Math.PI, // thetaLength — 圆柱底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆柱
            );
            cylinder1.rotateY(Math.PI * 0.75);
            const cylinderMesh1 = new THREE.Mesh(cylinder1, material1);
            // this.scene.add(cylinderMesh1);


            const plane1 = new THREE.PlaneGeometry(20, 16);
            // plane1.rotateY(Math.PI * -0.75);
            // plane1.rotateY(Math.PI * -0.5);
            plane1.translate(10, 0, 0);
            plane1.rotateY(Math.PI * 0.25);
            const planeMesh1 = new THREE.Mesh(plane1, material);
            // this.scene.add(planeMesh1);

            const plane2 = new THREE.PlaneGeometry(20, 16);
            plane2.translate(10, 0, 0);
            plane2.rotateY(Math.PI * 0.75);
            const planeMesh2 = new THREE.Mesh(plane2, material);
            // this.scene.add(planeMesh2);



            let r = this.r;
            let vt = this.verticalT;
            if (vt >= 90) vt = 89.9;
            let h = Math.sin(THREE.MathUtils.degToRad(vt)) * r;
            let cr1 = Math.cos(THREE.MathUtils.degToRad(vt)) * r;

            const cone1 = new THREE.ConeGeometry(
                cr1, // radius — 圆锥底部的半径，默认值为1
                h, // height — 圆锥的高度，默认值为1
                32, // radialSegments — 圆锥侧面周围的分段数，默认为32
                1, // heightSegments — 圆锥侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                2 * Math.PI, // thetaLength — 圆锥底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆锥
            );

            cone1.translate(0, -h / 2, 0);
            cone1.rotateX(Math.PI * 1);
            const coneMesh1 = new THREE.Mesh(cone1, material);
            // this.scene.add(coneMesh1); // 上


            let vb = this.verticalB;
            if (vb >= 90) vb = 89.9;
            let h1 = Math.sin(THREE.MathUtils.degToRad(vb)) * r;
            let cr2 = Math.cos(THREE.MathUtils.degToRad(vb)) * r;

            const cone2 = new THREE.ConeGeometry(
                cr2, // radius — 圆锥底部的半径，默认值为1
                h1, // height — 圆锥的高度，默认值为1
                32, // radialSegments — 圆锥侧面周围的分段数，默认为32
                1, // heightSegments — 圆锥侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                2 * Math.PI, // thetaLength — 圆锥底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆锥
            );
            cone2.translate(0, -h1 / 2, 0);

            const coneMesh2 = new THREE.Mesh(cone2, material);
            // this.scene.add(coneMesh2); // 下



            // this.a1 = new ThreeBSP(cylinder);
            // this.a2 = new ThreeBSP(cylinder1);
            // this.b1 = new ThreeBSP(plane1);
            // this.c1 = new ThreeBSP(plane2);






            const sphere = new THREE.SphereGeometry(
                20, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                0, // phiStart — 指定水平（经线）起始角度，默认值为0
                Math.PI * 2, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                Math.PI // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const sphereMesh = new THREE.Mesh(sphere, material1);
            // this.scene.add(sphereMesh);

            const circle1 = new THREE.CircleGeometry(cr1 * 1, 32);
            circle1.rotateX(Math.PI * 0.5);
            circle1.translate(0, h, 0);

            const circle2 = new THREE.CircleGeometry(cr2 * 1, 32);
            circle2.rotateX(Math.PI * 0.5);
            circle2.translate(0, -h1, 0);

            // this.a1 = new ThreeBSP(sphere);
            this.x1 = new ThreeBSP(circle1); // up
            this.y1 = new ThreeBSP(cone1);
            this.x2 = new ThreeBSP(circle2); // down
            this.y2 = new ThreeBSP(cone2);
            // this.b1 = new ThreeBSP(circle1);
            // this.c1 = new ThreeBSP(circle2);

            const sphere1 = new THREE.SphereGeometry(
                2, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                0, // phiStart — 指定水平（经线）起始角度，默认值为0
                Math.PI * 2, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                Math.PI // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            this.z1 = new ThreeBSP(sphere1);
        },
        init1Ogt00() {
            let r = this.r;
            let hl = this.horizontalL;
            if (hl >= 90) hl = 89.9;
            let h = Math.sin(THREE.MathUtils.degToRad(hl)) * r;
            let cr1 = Math.cos(THREE.MathUtils.degToRad(hl)) * r;

            const cone1 = new THREE.ConeGeometry(
                cr1, // radius — 圆锥底部的半径，默认值为1
                h, // height — 圆锥的高度，默认值为1
                32, // radialSegments — 圆锥侧面周围的分段数，默认为32
                1, // heightSegments — 圆锥侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                2 * Math.PI, // thetaLength — 圆锥底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆锥
            );

            cone1.translate(0, -h / 2, 0);
            cone1.rotateX(Math.PI * 1);
            cone1.rotateZ(Math.PI * -0.5);
            const material1 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide, transparent: true, opacity: 0.3, });
            const material = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide, transparent: true, opacity: 0.3, });
            const coneMesh1 = new THREE.Mesh(cone1, material);
            // this.scene.add(coneMesh1); // left


            let hr = this.horizontalR;
            if (hr >= 90) hr = 89.9;
            let h1 = Math.sin(THREE.MathUtils.degToRad(hr)) * r;
            let cr2 = Math.cos(THREE.MathUtils.degToRad(hr)) * r;

            const cone2 = new THREE.ConeGeometry(
                cr2, // radius — 圆锥底部的半径，默认值为1
                h1, // height — 圆锥的高度，默认值为1
                32, // radialSegments — 圆锥侧面周围的分段数，默认为32
                1, // heightSegments — 圆锥侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                2 * Math.PI, // thetaLength — 圆锥底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆锥
            );
            cone2.translate(0, -h1 / 2, 0);
            cone2.rotateZ(Math.PI * -0.5);

            const coneMesh2 = new THREE.Mesh(cone2, material);
            // this.scene.add(coneMesh2); // right




            const circle1 = new THREE.CircleGeometry(cr1 * 1, 32);
            circle1.rotateX(Math.PI * 0.5);
            circle1.translate(0, h, 0);
            circle1.rotateZ(Math.PI * -0.5);

            const circle2 = new THREE.CircleGeometry(cr2 * 1, 32);
            circle2.rotateX(Math.PI * 0.5);
            circle2.translate(0, -h1, 0);
            circle2.rotateZ(Math.PI * -0.5);


            this.v1 = new ThreeBSP(circle1); // left
            this.w1 = new ThreeBSP(cone1);
            this.v2 = new ThreeBSP(circle2); // right
            this.w2 = new ThreeBSP(cone2);

            const sphere1 = new THREE.SphereGeometry(
                2, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                0, // phiStart — 指定水平（经线）起始角度，默认值为0
                Math.PI * 2, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                Math.PI // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            this.z2 = new ThreeBSP(sphere1);
        },
        init1Ogt() {
            let hl = 60,
                hr = 150

            let r = 20,
                thetaLength = Math.PI * (hl / 180),
                thetaLength1 = Math.PI * (hr / 180)

            const cylinder = new THREE.CylinderGeometry(
                r, // radiusTop — 圆柱的顶部半径，默认值是1
                r, // radiusBottom — 圆柱的底部半径，默认值是1
                r, // height — 圆柱的高度，默认值是1
                32, // radialSegments — 圆柱侧面周围的分段数，默认为32
                1, // heightSegments — 圆柱侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                thetaLength, // thetaLength — 圆柱底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆柱
            );

            const material1 = new THREE.MeshBasicMaterial({ color: 0xffff00, wireframe: true, side: THREE.DoubleSide, transparent: true, opacity: 0.3, });
            const material = new THREE.MeshBasicMaterial({ color: 0xff00ff, wireframe: true, side: THREE.DoubleSide, transparent: true, opacity: 0.3, });
            const cylinderMesh = new THREE.Mesh(cylinder, material1);
            // this.scene.add(cylinderMesh);

            const plane1 = new THREE.PlaneGeometry(r, r);
            plane1.rotateY(Math.PI * 0.5);
            plane1.translate(0, 0, r / 2);
            const planeMesh1 = new THREE.Mesh(plane1, material);
            // this.scene.add(planeMesh1);

            const plane2 = new THREE.PlaneGeometry(r, r);
            plane2.translate(r / 2, 0, 0);
            plane2.rotateY(Math.PI * ((hl - 90) / 180));
            const planeMesh2 = new THREE.Mesh(plane2, material);
            // this.scene.add(planeMesh2);



            const cylinder1 = new THREE.CylinderGeometry(
                r, // radiusTop — 圆柱的顶部半径，默认值是1
                r, // radiusBottom — 圆柱的底部半径，默认值是1
                r, // height — 圆柱的高度，默认值是1
                32, // radialSegments — 圆柱侧面周围的分段数，默认为32
                1, // heightSegments — 圆柱侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                thetaLength1, // thetaLength — 圆柱底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆柱
            );
            cylinder1.rotateY(-thetaLength1);

            const cylinderMesh1 = new THREE.Mesh(cylinder1, material1);
            // this.scene.add(cylinderMesh1);

            const plane3 = new THREE.PlaneGeometry(r, r);
            plane3.rotateY(Math.PI * 0.5);
            plane3.translate(0, 0, r / 2);
            const planeMesh3 = new THREE.Mesh(plane3, material);
            // this.scene.add(planeMesh3);

            const plane4 = new THREE.PlaneGeometry(r, r);
            plane4.translate(-r / 2, 0, 0);
            plane4.rotateY(Math.PI * ((90 - hr) / 180));
            const planeMesh4 = new THREE.Mesh(plane4, material);
            // this.scene.add(planeMesh4);







            this.a1 = new ThreeBSP(cylinder);
            this.b1 = new ThreeBSP(plane1);
            this.c1 = new ThreeBSP(plane2);
            this.a2 = new ThreeBSP(cylinder1);
            this.b2 = new ThreeBSP(plane3);
            this.c2 = new ThreeBSP(plane4);

        },
        initMesh(pointsArr) {
            /* let points = pointsArr.map(
                (d) => new THREE.Vector3(d[0], d[1], d[2])
            );

            let color = null;
            if (this.type === 1) {
                color = 0x0000ff;
            } else if (this.type === 2) {
                color = 0x008000;
            } else if (this.type === 3) {
                color = 0xff4500;
            } else {
                color = 0x0000ff;
            }

            let material = new THREE.MeshPhongMaterial({
                emissive: color,
                color: 0x4c4c4c,
                transparent: true,
                opacity: 0.3,
                lightMapIntensity: 0.1,
                side: THREE.DoubleSide,
            });

            let tixing = new ConvexGeometry(points);
            //通过ConvexGeometry凸包绘制一个梯台，当然也可以使用ExtrudeGeometry挤压几何体，
            let tixingMesh = new THREE.Mesh(tixing, material);
            tixingMesh.name = "cube";
            this.scene.add(tixingMesh); */

            this.$emit('loadingDone', 'carDone');



            // this.initLeft();
            // this.initTop();


            // this.initLeft1();
            // this.initTop1();


            // this.initDemo();
            // this.initDemo1();




            // this.initOgtDemo();
            // this.initOgtDemo1();


            this.initOgt();
            this.initOgt1();

            // this.initOgt0();
            // this.initOgt01();



            this.init1Ogt0();
            this.init1Ogt00();
            // this.init1Ogt();




            // console.log(this.group1);


            // var m = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });


            // var bsp = this.group1.subtract(this.group2);
            // var mesh = bsp.toMesh(m);

            // this.scene.add(mesh);

            // console.log(bsp);

            // this.scene.add(bsp);



            // intersect （交集） union （并集） subtract （差集）

            /* var m = new THREE.MeshBasicMaterial({ color: 0xff0000, side: THREE.DoubleSide });
            const resultBSP = this.group1.union(this.group2).toMesh(m);
            console.log(resultBSP);
            this.scene.add(resultBSP); */



            // var m = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });
            // let m = new THREE.MeshPhongMaterial({ emissive: 0xff00ff, color: 0x4c4c4c, transparent: true, opacity: 0.3, side: THREE.DoubleSide });
            // var m = new THREE.MeshBasicMaterial({ color: 0xffaa00, transparent: true, blending: THREE.AdditiveBlending });
            var m = new THREE.MeshBasicMaterial({ color: 0xffaa00, wireframe: true });


            // let m = new THREE.MeshPhongMaterial({
            //     emissive: color,
            //     color: 0x4c4c4c,
            //     transparent: true,
            //     opacity: 0.3,
            //     lightMapIntensity: 0.1,
            //     side: THREE.DoubleSide,
            // });



            // const resultBSP = this.a1.subtract(this.b1).subtract(this.c1).union(this.a2).union(this.b2).union(this.c2).toMesh(m);
            // const resultBSP = (this.a1.subtract(this.b1).subtract(this.c1)).subtract(this.a2.subtract(this.c2).subtract(this.b2)).toMesh(m);

            // const resultBSP = (this.a2.subtract(this.b2).subtract(this.c2)).subtract(this.a1.subtract(this.b1).subtract(this.c1)).toMesh(m);
            // const resultBSP = this.a2.subtract(this.b2.subtract(this.c2))

            // let aa = new ThreeBSP(this.a1.subtract(this.b1).subtract(this.c1));
            // let bb = new ThreeBSP(this.a2.subtract(this.b2).subtract(this.c2));


            // m = new THREE.MeshBasicMaterial({
            /* m = new THREE.MeshPhongMaterial({
                emissive: 0x0000ff,
                color: 0x4c4c4c,
                transparent: true,
                opacity: 0.3,
                lightMapIntensity: 0.1,
                side: THREE.DoubleSide,
            }); */


            // const resultBSP = this.a1.subtract(this.b1).subtract(this.c1).toMesh(m);



            // 都小于90
            // const resultBSP = this.a2.intersect(this.c2).subtract(this.b2).intersect(this.a1.subtract(this.b1).subtract(this.c1)).toMesh(m);
            // const resultBSP = this.a1.subtract(this.b1).subtract(this.c1).intersect(this.a2.subtract(this.b2).intersect(this.c2)).toMesh(m);
            // const resultBSP = this.a1.subtract(this.b1).subtract(this.c1).intersect(this.a2.subtract(this.b2).intersect(this.c2))
            //     .subtract(this.x1.subtract(this.y1).subtract(this.z1).intersect(this.x2.subtract(this.y2).intersect(this.z2)))
            //     .toMesh(m);

            // 大于90
            // const resultBSP = this.a1.subtract(this.b1.intersect(this.c1)).toMesh(m);
            // 小于90
            // const resultBSP = this.a2.subtract(this.b2).intersect(this.c2).toMesh(m);
            // 1大于90 2小于90
            // const resultBSP = this.a1.subtract(this.b1.intersect(this.c1)).intersect(this.a2.subtract(this.b2).intersect(this.c2)).toMesh(m);
            // const resultBSP = this.a1.subtract(this.b1.intersect(this.c1)).intersect(this.a2.subtract(this.b2).intersect(this.c2))
            // .subtract(this.x1.subtract(this.y1.intersect(this.z1)).intersect(this.x2.subtract(this.y2).intersect(this.z2))).toMesh(m);

            // 小于90
            // const resultBSP = this.a1.subtract(this.b1).subtract(this.c1).toMesh(m);
            // 大于90
            // const resultBSP = this.a2.subtract(this.b2.subtract(this.c2)).toMesh(m);
            // 1小于90 2大于90
            // const resultBSP = this.a1.subtract(this.b1).subtract(this.c1).intersect(this.a2.subtract(this.b2.subtract(this.c2))).toMesh(m);
            // const resultBSP = this.a1.subtract(this.b1).subtract(this.c1).intersect(this.a2.subtract(this.b2.subtract(this.c2)))
            //         .subtract(this.x1.subtract(this.y1).subtract(this.z1).intersect(this.x2.subtract(this.y2.subtract(this.z2)))).toMesh(m);

            // 都大于90
            // const resultBSP = this.a1.subtract(this.b1.intersect(this.c1)).intersect(this.a2.subtract(this.b2.subtract(this.c2))).toMesh(m);
            // const resultBSP = this.a1.subtract(this.b1.intersect(this.c1)).intersect(this.a2.subtract(this.b2.subtract(this.c2)))
            //         .subtract(this.x1.subtract(this.y1.intersect(this.z1)).intersect(this.x2.subtract(this.y2.subtract(this.z2)))).toMesh(m);







            // 带盲区距离
            // const resultBSP = 
            // this.a1.subtract(this.b1.intersect(this.c1)).intersect(this.a2.subtract(this.b2.subtract(this.c2)))
            //                     .subtract
            //                     (this.x1.subtract(this.y1.intersect(this.z1)).intersect(this.x2.subtract(this.y2.subtract(this.z2))))
            //                     .toMesh(m);







            // ogt
            // const resultBSP = this.a1.subtract(this.b1).intersect(this.c1).intersect(this.a2.subtract(this.b2).intersect(this.c2)).toMesh(m);
            // resultBSP = resultBSP.subtract(this.a2);


            // ogt 带盲区距离
            // const resultBSP = (this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1).intersect(this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)))
            // .subtract(this.x1.intersect(this.w1).subtract(this.y1).subtract(this.z1).intersect(this.x2.intersect(this.w2).subtract(this.y2).intersect(this.z2)))
            // .toMesh(m);




            // intersect （交集） union （并集） subtract （差集）


            // ogt 相加都小于180 
            // const resultBSP =
            //     this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1).intersect(this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2))
            //         .subtract(this.x1.intersect(this.w1).subtract(this.y1).subtract(this.z1).intersect(this.x2.intersect(this.w2).subtract(this.y2).intersect(this.z2)))
            //         .toMesh(m);

            // ogt 左右相加大于180  上下相加小于180
            // const resultBSP = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)).toMesh(m);
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2).toMesh(m);
            // const resultBSP =
            //     this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)).intersect(this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2))
            //         .subtract(this.x1.intersect(this.w1).subtract(this.y1.intersect(this.z1)).intersect(this.x2.intersect(this.w2).subtract(this.y2).intersect(this.z2)))
            //         .toMesh(m);

            // ogt 左右相加小于180  上下相加大于180
            // const resultBSP = this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1).toMesh(m);
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2)).toMesh(m);
            // const resultBSP = this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1).intersect(this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2)))
            //     .subtract(this.x1.intersect(this.w1).subtract(this.y1).subtract(this.z1).intersect(this.x2.intersect(this.w2).subtract(this.y2.subtract(this.z2))))
            //     .toMesh(m);


            // ogt 相加都大于180 
            // const resultBSP = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)).toMesh(m);
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2)).toMesh(m);
            // const resultBSP = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)).intersect(this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2)))
            //     .subtract(this.x1.intersect(this.w1).subtract(this.y1.intersect(this.z1)).intersect(this.x2.intersect(this.w2).subtract(this.y2.subtract(this.z2))))
            //     .toMesh(m);





            // ogt new
            // ogt 左右相加大于180  上下相加小于180
            // const resultBSP = this.a2.intersect(this.b2.subtract(this.c2))
            // const resultBSP = this.a1.subtract(this.b1).subtract(this.c1)
            //     .union(this.a2.intersect(this.b2.subtract(this.c2)))
            //     .subtract(this.x1).subtract(this.y1)
            //     .toMesh(m);
            // const resultBSP = this.a1.toMesh(m);

            // const resultBSP = this.a1.subtract(this.b1).subtract(this.x1).intersect(this.c1).subtract(this.y1).toMesh(m);
            // 大于180
            // const resultBSP = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)).subtract(this.y1).subtract(this.x1).toMesh(m);
            // const resultBSP = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1))
            // .subtract(this.x1).subtract(this.y1).subtract(this.y2).intersect(this.x2).subtract(this.z1)
            // .toMesh(m);
            // 小于180
            // const resultBSP = this.y2
            // const resultBSP = this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1)
            // .subtract(this.x1).subtract(this.y1).intersect(this.x2).subtract(this.y2).subtract(this.z1)
            // .toMesh(m);



            let cube = "";


            // ogt new-new
            // vt<=90 vb<=90 hl+hr<=180  initOgt  init1Ogt0
            // const resultBSP = this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1)
            //     .subtract(this.x1).subtract(this.y1).intersect(this.x2).subtract(this.y2).subtract(this.z1)
            //     .toMesh(m);

            // vt<=90 vb<=90 hl+hr>180&<360  initOgt  init1Ogt0
            // const resultBSP = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1))
            //     .subtract(this.x1).subtract(this.y1).intersect(this.x2).subtract(this.y2).subtract(this.z1)
            //     .toMesh(m);

            // vt>90 vb<90 vt+vb<=180 hl<90 hr<90  initOgt1    init1Ogt00
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
            //     .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2)
            //     .toMesh(m);

            // cube = `this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
            // .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2)`
            // cube = cube + '.toMesh(m)';
            // const resultBSP = eval(cube);
            // let a = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)


            // (120 45) vt>90||vb>90 vt+vb>180 (60 45) hl<90 hr<90  initOgt1    init1Ogt00
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
            //     .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2)
            //     .toMesh(m);
            // const resultBSP = this.a2
            //     .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2)
            //     .toMesh(m);

            // (45 120) vt<=90 vb>90 vt+vb<=180 (60 45) hl<90 hr<90  initOgt  initOgt1  init1Ogt00   init1Ogt0
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
            //     .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2)
            //     .toMesh(m);

            // (240 60) vt>90 vb<=90 180<vt+vb<360 (60 30) hl<90 hr<90  initOgt  initOgt1    init1Ogt00
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
            //     .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2)
            //     .toMesh(m);

            // (75 150) vt<=90 vb>90 180<vt+vb<360 (30 60) hl<90 hr<90  initOgt  initOgt1  init1Ogt00  init1Ogt0
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
            //     .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2)
            //     .toMesh(m);

            // (120 60) vt>90 vb<90 vt+vb<=180 (150 60)  90<hl<180 hr<90  initOgt  initOgt1    init1Ogt00
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
            //     .intersect(this.v2).subtract(this.w2)
            //     .union(this.d1.subtract(this.b1).intersect(this.e1))
            //     .intersect(this.x2).subtract(this.y2)
            //     .toMesh(m);

            // (45 120) vt<=90 vb>90 vt+vb<=180 (150 60)  90<hl<180 hr<90  initOgt  initOgt1  init1Ogt00  init1Ogt0
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
            //     .intersect(this.v2).subtract(this.w2)
            //     .union(this.d1.subtract(this.b1).intersect(this.e1))
            //     .subtract(this.x1).subtract(this.y1)
            //     .toMesh(m);

            // (240 60) vt>90 vb<90 180<vt+vb<360 (150 60)  90<hl<180 hr<90  initOgt  initOgt1    init1Ogt00
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
            //     .intersect(this.v2).subtract(this.w2)
            //     .union(this.d1.subtract(this.b1).intersect(this.e1))
            //     .intersect(this.x2).subtract(this.y2)
            //     .toMesh(m);

            // (75 150) vt<=90 vb>90 180<vt+vb<360 (135 75)  90<hl<180 hr<90  initOgt  initOgt1  init1Ogt00  init1Ogt0
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
            //     .intersect(this.v2).subtract(this.w2)
            //     .union(this.d1.subtract(this.b1).intersect(this.e1))
            //     .subtract(this.x1).subtract(this.y1)
            //     .toMesh(m);

            // (120 60) vt>90 vb<90 vt+vb<=180 (60 150) hl<90 90<hr<180  initOgt  initOgt1    init1Ogt00
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
            //     .subtract(this.v1).subtract(this.w1)
            //     .union(this.a1.subtract(this.c1).subtract(this.e1))
            //     .intersect(this.x2).subtract(this.y2)
            //     .toMesh(m);
            
            // (45 120) vt<=90 vb>90 vt+vb<=180 (45 150) hl<90 90<hr<180  initOgt  initOgt1  init1Ogt00  init1Ogt0
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
            //     .subtract(this.v1).subtract(this.w1)
            //     .union(this.a1.subtract(this.c1).subtract(this.e1))
            //     .subtract(this.x1).subtract(this.y1)
            //     .toMesh(m);

            // (210 60) vt>90 vb<90 180<vt+vb<360 (60 150) hl<90 90<hr<180  initOgt  initOgt1    init1Ogt00   init1Ogt0
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
            //     .subtract(this.v1).subtract(this.w1)
            //     .union(this.a1.subtract(this.c1).subtract(this.e1))
            //     .intersect(this.x2).subtract(this.y2)
            //     .toMesh(m);

            // (75 150) vt<=90 vb>90 180<vt+vb<360 (54 120) hl<90 90<hr<180  initOgt  initOgt1  init1Ogt00  init1Ogt0
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
            //     .subtract(this.v1).subtract(this.w1)
            //     .union(this.a1.subtract(this.c1).subtract(this.e1))
            //     .subtract(this.x1).subtract(this.y1)
            //     .toMesh(m);

            // (120 60) vt>90 vb<90 vt+vb<=180 (60 240) hl<90 hr>180  initOgt  initOgt1    init1Ogt00
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
            //     .subtract(this.v1).subtract(this.w1)
            //     .union(this.a1.subtract(this.c1.intersect(this.e1)))
            //     .intersect(this.x2).subtract(this.y2)
            //     .toMesh(m);

            // (45 120) vt<=90 vb>90 vt+vb<=180 (75 225) hl<90 hr>180  initOgt  initOgt1  init1Ogt00  init1Ogt0
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
            //     .subtract(this.v1).subtract(this.w1)
            //     .union(this.a1.subtract(this.c1.intersect(this.e1)))
            //     .subtract(this.x1).subtract(this.y1)
            //     .toMesh(m);

            // (210 60) vt>90 vb<90 180<vt+vb<360 (60 240) hl<90 hr>180  initOgt  initOgt1    init1Ogt00   init1Ogt0
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
            //     .subtract(this.v1).subtract(this.w1)
            //     .union(this.a1.subtract(this.c1.intersect(this.e1)))
            //     .intersect(this.x2).subtract(this.y2)
            //     .toMesh(m);

            // (75 150) vt<=90 vb>90 180<vt+vb<360 (60 210) hl<90 hr>180  initOgt  initOgt1  init1Ogt00  init1Ogt0
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
            //     .subtract(this.v1).subtract(this.w1)
            //     .union(this.a1.subtract(this.c1.intersect(this.e1)))
            //     .subtract(this.x1).subtract(this.y1)
            //     .toMesh(m);

            // (120 45) vt>90 vb<90 vt+vb<=180 (240 60)  hl>180 hr<90  initOgt  initOgt1    init1Ogt00   init1Ogt0
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
            //     .intersect(this.v2).subtract(this.w2)
            //     .union(this.d1.subtract(this.b1.subtract(this.e1)))
            //     .intersect(this.x2).subtract(this.y2)
            //     .toMesh(m);

            // (45 120) vt<=90 vb>90 vt+vb<=180 (240 60)  hl>180 hr<90  initOgt  initOgt1  init1Ogt00  init1Ogt0
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
            //     .intersect(this.v2).subtract(this.w2)
            //     .union(this.d1.subtract(this.b1.subtract(this.e1)))
            //     .subtract(this.x1).subtract(this.y1)
            //     .toMesh(m);

            // (210 60) vt>90 vb<90 180<vt+vb<360 (225 45)  hl>180 hr<90  initOgt  initOgt1    init1Ogt00   init1Ogt0
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
            //     .intersect(this.v2).subtract(this.w2)
            //     .union(this.d1.subtract(this.b1.subtract(this.e1)))
            //     .intersect(this.x2).subtract(this.y2)
            //     .toMesh(m);

            // (75 150) vt<=90 vb>90 180<vt+vb<360 (270 45)  hl>180 hr<90  initOgt  initOgt1  init1Ogt00  init1Ogt0
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
            //     .intersect(this.v2).subtract(this.w2)
            //     .union(this.d1.subtract(this.b1.subtract(this.e1)))
            //     .subtract(this.x1).subtract(this.y1)
            //     .toMesh(m);

            // (120 45) vt>90 vb<90 vt+vb<=180 (120 150)  90<hl<180 90<hr<180  initOgt  initOgt1  init1Ogt00    init1Ogt0
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
            //     .union(this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)))
            //     .intersect(this.x2).subtract(this.y2)
            //     .toMesh(m);

            // (120 60) vt>90 vb<90 vt+vb<=180 (150 120) hl>90 hr>90  initOgt  initOgt1 init1Ogt00
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
            //     .union(this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)))
            //     .intersect(this.x2).subtract(this.y2)
            //     .toMesh(m);

            // (45 120) vt<=90 vb>90 vt+vb<=180 (210 120) hl>90 hr>90  initOgt  initOgt1  init1Ogt00  init1Ogt0
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
            //     .union(this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)))
            //     .subtract(this.x1).subtract(this.y1)
            //     .toMesh(m);

            // (210 60) vt>90 vb<90 180<vt+vb<360 (120 150) hl>90 hr>90  initOgt  initOgt1    init1Ogt00   init1Ogt0
            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
            //     .union(this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)))
            //     .intersect(this.x2).subtract(this.y2)
            //     .toMesh(m);

            // (75 150) vt<=90 vb>90 180<vt+vb<360 (180 120) hl>90 hr>90  initOgt  initOgt1  init1Ogt00  init1Ogt0
            const resultBSP = this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                .union(this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)))
                .subtract(this.x1).subtract(this.y1)
                .toMesh(m);

            // (300 60) vt>90 vb<90 vt+vb=360 (60 75) hl<90 hr<90 hl+hr<180  initOgt  initOgt1    init1Ogt00   init1Ogt0
            // const resultBSP = this.a2
            //     .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2)
            //     .toMesh(m); 
            // 120 45
            // const resultBSP = this.a2
            //     .intersect(this.v2).subtract(this.w2)
            //     .toMesh(m);
            // 45 120
            // const resultBSP = this.a2
            //     .subtract(this.v1).subtract(this.w1)
            //     .toMesh(m);



            // const resultBSP = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1))
            //     .toMesh(m);




            // const resultBSP = this.d1.subtract(this.b1.subtract(this.e1))
            //     .toMesh(m);

            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
            //     .intersect(this.v2).subtract(this.w2)
            //     .union(this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)))
            //     .intersect(this.x2).subtract(this.y2)
            //     .toMesh(m);





            // 非ogt new
            // 都小于90
            // const resultBSP = this.a1.subtract(this.b1).subtract(this.c1)
            //     .toMesh(m);
            // 大于90
            // const resultBSP = this.a1.subtract(this.b1.intersect(this.c1))
            //     .subtract(this.x1).subtract(this.y1).intersect(this.x2).subtract(this.y2).subtract(this.z1)
            //     // .subtract(this.x1).subtract(this.y1).subtract(this.y2).intersect(this.x2).subtract(this.z1)
            //     .toMesh(m);






            // 非ogt new--new 垂直大于180
            // const resultBSP = this.a2.subtract(this.b2.subtract(this.c2))
            //     .subtract(this.x1).subtract(this.y1).intersect(this.x2).subtract(this.y2)
            //     .toMesh(m);


            // const resultBSP = this.a1.subtract(this.b1.intersect(this.c1))
            //     // const resultBSP = this.a2.subtract(this.b2.subtract(this.c2))
            //     .union(this.a2.subtract(this.b2.subtract(this.c2)))
            //     .toMesh(m);



            // const resultBSP = this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1).toMesh(m);


            // left大于90 
            // const resultBSP = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1))
            // this.a1.subtract(this.c1)  this.d1.subtract(this.b1)
            // const resultBSP = this.a1.subtract(this.c1).intersect(this.d1.subtract(this.b1))     
            // const resultBSP = this.d1.subtract(this.b1).intersect(this.a1).intersect(this.c1)
            // const resultBSP = this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1)
            // .intersect(this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2))
            // .toMesh(m);



            // const resultBSP = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2).toMesh(m);

            // const resultBSP = this.a1.toMesh(m);

            // const resultBSP =
            //     this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1).intersect(this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2))
            //         .subtract(this.x1.intersect(this.w1).subtract(this.y1).subtract(this.z1).intersect(this.x2.intersect(this.w2).subtract(this.y2).intersect(this.z2)))
            //         .toMesh(m);

            // const resultBSP =
            //     this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1)
            //         .toMesh(m);



            // console.log(resultBSP);
            console.log('resultBSP');
            this.scene.add(resultBSP);


            /* 
            ADDITION
            SUBTRACTION
            DIFFERENCE
            INTERSECTION
            */
            /* const evaluator = new Evaluator();
            let result;
            result = evaluator.evaluate(this.group1, this.group2, INTERSECTION);

            console.log(this.group1); */

            // result.castShadow = true
            // result.receiveShadow = true;
            // this.scene.add(result);



            // console.log(ThreeBSP);
        },
        /*
         * 初始化非ogt模型
         * @param {*} coordinate 配置参数
         * @param {*} vh v 垂直  h 水平
         * @param {*} nf n 盲区距离  f 探测距离
         */
        initContent0(coordinate, vh, nf) {
            let r = 0, deg = 0, rate = 1;
            // let a = 100 / (this.scale / 0.6);
            let a = 1;

            // 若探测距离超出最大值，则默认为10000，盲区距离按比例展示 
            // 值为测试出来的预估值 超过的话ThreeBSP会报内存溢出
            let maxR = 10000;

            if ((coordinate.farDistance * a) > maxR) {
                if (nf === 'n') {
                    rate = (coordinate.farDistance * a) / maxR;
                    r = ((coordinate.nearDistance * a) / rate).toFixed();
                } else {
                    r = maxR - 3.3;
                }
            } else {
                if (nf === 'n') {
                    r = coordinate.nearDistance * a;
                } else {
                    r = coordinate.farDistance * a;
                }
            }

            if (vh === 'v') {
                deg = coordinate.fovV / 2;
                // if (coordinate.fovH >= 47 && coordinate.fovH <= 53 && coordinate.fovV == 30) {
                //     deg = 31;
                // }

                // if (deg == 80) deg = 79;
                // if (deg == 20) deg = 19;
                // if (deg % 10 === 0 && deg % 90 != 0) deg = deg + 0.7;
            } else {
                deg = coordinate.fovH / 2;
                // if (deg >= 47 && deg <= 53) deg = 53;
                // if (deg >= 17 && deg <= 23) deg = 17;
                // if (deg >= 117 && deg <= 123) deg = 121;
                // if (deg >= 147 && deg <= 153) deg = 148;
            }

            // 180°时融合有问题
            // if (deg % 90 === 0) deg = deg - 0.5;


            let phiStart = Math.PI * ((90 - deg) / 180),
                phiLength = Math.PI * (deg * 2 / 180),
                thetaStart = 0,
                thetaLength = Math.PI;

            const geometry = new THREE.SphereGeometry(
                r, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });
            const sphere = new THREE.Mesh(geometry, material);


            const geometry1 = new THREE.CircleGeometry(
                r, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );
            const material1 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle1 = new THREE.Mesh(geometry1, material1); // left top



            const geometry2 = new THREE.CircleGeometry(
                r, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI * 1 // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );
            const material2 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle2 = new THREE.Mesh(geometry2, material2); // right bottom


            if (vh === 'v') {
                sphere.rotateZ(Math.PI * 0.5);
                circle1.rotateX(phiStart);
                circle2.rotateX(-phiStart - Math.PI);

                if (nf === 'n') {
                    this.x2 = new ThreeBSP(sphere);
                    this.y2 = new ThreeBSP(circle1);
                    this.z2 = new ThreeBSP(circle2);
                } else {
                    this.a2 = new ThreeBSP(sphere);
                    this.b2 = new ThreeBSP(circle1);
                    this.c2 = new ThreeBSP(circle2);
                }
            } else {
                circle1.rotateZ(Math.PI * -0.5);
                circle1.rotateX(phiStart);
                circle2.rotateZ(Math.PI * 0.5);
                circle2.rotateX(phiStart);

                if (nf === 'n') {
                    this.x1 = new ThreeBSP(sphere);
                    this.y1 = new ThreeBSP(circle1);
                    this.z1 = new ThreeBSP(circle2);
                } else {
                    this.a1 = new ThreeBSP(sphere);
                    this.b1 = new ThreeBSP(circle1);
                    this.c1 = new ThreeBSP(circle2);
                }
            }


            if (deg >= 180) {
                const sphere1 = new THREE.SphereGeometry(
                    r, // radius — 球体半径，默认为1
                    32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                    16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                    0, // phiStart — 指定水平（经线）起始角度，默认值为0
                    Math.PI * 2, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                    0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                    Math.PI // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
                );

                if (vh === 'v') {
                    this.a2 = new ThreeBSP(sphere1);
                } else {
                    this.a1 = new ThreeBSP(sphere1);
                }

            }
        },
        // 配置以水平视场角为地基进行的裁剪
        initContent01(coordinate) {
            let far = coordinate.farDistance,
                near = coordinate.nearDistance,
                fovV = coordinate.fovV / 2;

            if (fovV >= 90) fovV = 89.9;

            let h = Math.sin(THREE.MathUtils.degToRad(fovV)) * far,
                r1 = Math.cos(THREE.MathUtils.degToRad(fovV)) * far;

            const cone1 = new THREE.ConeGeometry(
                r1, // radius — 圆锥底部的半径，默认值为1
                h, // height — 圆锥的高度，默认值为1
                32, // radialSegments — 圆锥侧面周围的分段数，默认为32
                1, // heightSegments — 圆锥侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                2 * Math.PI, // thetaLength — 圆锥底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆锥
            );

            cone1.translate(0, -h / 2, 0);
            cone1.rotateX(Math.PI * 1);

            const cone2 = new THREE.ConeGeometry(
                r1, // radius — 圆锥底部的半径，默认值为1
                h, // height — 圆锥的高度，默认值为1
                32, // radialSegments — 圆锥侧面周围的分段数，默认为32
                1, // heightSegments — 圆锥侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                2 * Math.PI, // thetaLength — 圆锥底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆锥
            );
            cone2.translate(0, -h / 2, 0);



            const circle01 = new THREE.CircleGeometry(h * 0.1, 32);
            circle01.rotateX(Math.PI * 0.5);
            circle01.translate(0, h, 0);

            const circle02 = new THREE.CircleGeometry(h * 0.1, 32);
            circle02.rotateX(Math.PI * 0.5);
            circle02.translate(0, -h, 0);


            if (near > 0) {
                const sphere1 = new THREE.SphereGeometry(
                    near, // radius — 球体半径，默认为1
                    32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                    16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                    0, // phiStart — 指定水平（经线）起始角度，默认值为0
                    Math.PI * 2, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                    0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                    Math.PI // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
                );
                this.z1 = new ThreeBSP(sphere1);
            }


            this.x1 = new ThreeBSP(circle01); // up
            this.y1 = new ThreeBSP(cone1);
            this.x2 = new ThreeBSP(circle02); // down
            this.y2 = new ThreeBSP(cone2);
        },
        // 配置以垂直视场角为地基进行的裁剪
        initContent02(coordinate) {
            let far = coordinate.farDistance,
                near = coordinate.nearDistance,
                fovH = coordinate.fovH / 2;

            if (fovH >= 90) fovH = 89.9;

            let h = Math.sin(THREE.MathUtils.degToRad(fovH)) * far,
                r1 = Math.cos(THREE.MathUtils.degToRad(fovH)) * far;

            const cone1 = new THREE.ConeGeometry(
                r1, // radius — 圆锥底部的半径，默认值为1
                h, // height — 圆锥的高度，默认值为1
                32, // radialSegments — 圆锥侧面周围的分段数，默认为32
                1, // heightSegments — 圆锥侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                2 * Math.PI, // thetaLength — 圆锥底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆锥
            );

            cone1.translate(0, -h / 2, 0);
            cone1.rotateX(Math.PI * 1);
            cone1.rotateZ(Math.PI * 0.5);

            const cone2 = new THREE.ConeGeometry(
                r1, // radius — 圆锥底部的半径，默认值为1
                h, // height — 圆锥的高度，默认值为1
                32, // radialSegments — 圆锥侧面周围的分段数，默认为32
                1, // heightSegments — 圆锥侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                2 * Math.PI, // thetaLength — 圆锥底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆锥
            );
            cone2.translate(0, -h / 2, 0);
            cone2.rotateZ(Math.PI * 0.5);



            const circle01 = new THREE.CircleGeometry(h * 0.1, 32);
            circle01.rotateX(Math.PI * 0.5);
            circle01.translate(0, h, 0);
            circle01.rotateZ(Math.PI * 0.5);

            const circle02 = new THREE.CircleGeometry(h * 0.1, 32);
            circle02.rotateX(Math.PI * 0.5);
            circle02.translate(0, -h, 0);
            circle02.rotateZ(Math.PI * 0.5);


            if (near > 0) {
                const sphere1 = new THREE.SphereGeometry(
                    near, // radius — 球体半径，默认为1
                    32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                    16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                    0, // phiStart — 指定水平（经线）起始角度，默认值为0
                    Math.PI * 2, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                    0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                    Math.PI // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
                );
                this.z2 = new ThreeBSP(sphere1);
            }


            this.v1 = new ThreeBSP(circle01); // left 好像写反了吧？
            this.w1 = new ThreeBSP(cone1);
            this.v2 = new ThreeBSP(circle02); // right
            this.w2 = new ThreeBSP(cone2);
        },
        /**
         * 初始化ogt模型
         * @param {*} coordinate 配置参数
         * @param {*} vh v 垂直  h 水平
         * @param {*} nf n 盲区距离  f 探测距离
         */
        initContentOgt(coordinate, vh, nf) {
            let r = 0, deg = 0, deg1 = 0, rate = 1;
            // let a = 100 / (this.scale / 0.6);
            let a = 1;

            let maxR = 10000;

            // 10000为预估 超过的话ThreeBSP会报内存溢出
            // 若探测距离超出最大值，则默认为10000，盲区距离按比例展示
            if ((coordinate.farDistance * a) > maxR) {
                if (nf === 'n') {
                    rate = (coordinate.farDistance * a) / maxR;
                    r = (coordinate.nearDistance * a) / rate;
                } else {
                    r = maxR - 3;
                }
            } else {
                if (nf === 'n') {
                    r = coordinate.nearDistance * a;
                } else {
                    r = coordinate.farDistance * a;
                }
            }

            if (vh === 'v') {
                deg = coordinate.fovVBottom;
                deg1 = coordinate.fovVTop;
            } else {
                deg = coordinate.fovHRight;
                deg1 = coordinate.fovHLeft;
            }

            if (deg == 0) deg = 1
            if (deg1 == 0) deg1 = 1

            // 180°时融合有问题
            // if ((deg + deg1) % 180 === 0) {
            //     if (deg > 1) {
            //         deg = deg - 0.1;
            //     } else {
            //         deg1 = deg1 - 0.1;
            //     }
            // }


            let phiStart = Math.PI * ((90 - deg) / 180),
                phiLength = Math.PI * (deg / 180),
                thetaStart = 0,
                thetaLength = Math.PI;

            const geometry = new THREE.SphereGeometry(
                r, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });

            const sphere = new THREE.Mesh(geometry, material); // 右 下




            let phiStart0 = Math.PI * (90 / 180),
                phiLength0 = Math.PI * (deg1 / 180),
                thetaStart0 = 0,
                thetaLength0 = Math.PI;

            const geometry0 = new THREE.SphereGeometry(
                r, // radius — 球体半径，默认为1
                32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                phiStart0, // phiStart — 指定水平（经线）起始角度，默认值为0
                phiLength0, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                thetaStart0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                thetaLength0 // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
            );
            const material0 = new THREE.MeshBasicMaterial({ color: 0xff00ff, side: THREE.DoubleSide });

            const sphere0 = new THREE.Mesh(geometry0, material0); // 左 上



            const geometry1 = new THREE.CircleGeometry(
                r, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material1 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle1 = new THREE.Mesh(geometry1, material1); // left top



            const geometry2 = new THREE.CircleGeometry(
                r, // radius — 圆形的半径，默认值为1
                32, // segments — 分段（三角面）的数量，最小值为3，默认值为32
                0, // thetaStart — 第一个分段的起始角度，默认为0。（three o'clock position）
                Math.PI // thetaLength — 圆形扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆
            );

            const material2 = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
            const circle2 = new THREE.Mesh(geometry2, material2); // right bottom

            
            const circle3 = new THREE.Mesh(geometry1, material1);
            circle3.rotateZ(Math.PI * -0.5);
            circle3.rotateX(Math.PI * 0.5);


            if (vh === 'v') {
                sphere.rotateZ(Math.PI * 0.5);
                sphere0.rotateZ(Math.PI * 0.5);
                circle1.rotateX(Math.PI * ((90 - deg1) / 180));
                circle2.rotateX(-phiStart - Math.PI);

                if (nf === 'n') {
                    this.x2 = new ThreeBSP(sphere);
                    this.y2 = new ThreeBSP(circle1);
                    this.z2 = new ThreeBSP(circle2);
                    this.w2 = new ThreeBSP(sphere0);
                } else {
                    this.a2 = new ThreeBSP(sphere);
                    this.b2 = new ThreeBSP(circle1);
                    this.c2 = new ThreeBSP(circle2);
                    this.d2 = new ThreeBSP(sphere0);
                }
            } else {
                circle1.rotateZ(Math.PI * -0.5);
                circle1.rotateX(Math.PI * ((90 - deg1) / 180));
                circle2.rotateZ(Math.PI * 0.5);
                circle2.rotateX(phiStart);

                if (nf === 'n') {
                    this.x1 = new ThreeBSP(sphere);
                    this.y1 = new ThreeBSP(circle1);
                    this.z1 = new ThreeBSP(circle2);
                    this.w1 = new ThreeBSP(sphere0);
                } else {
                    this.a1 = new ThreeBSP(sphere);
                    this.b1 = new ThreeBSP(circle1);
                    this.c1 = new ThreeBSP(circle2);
                    this.d1 = new ThreeBSP(sphere0);
                }

                this.e1 = new ThreeBSP(circle3);
            }

            if (deg + deg1 >= 360) {
                const sphere1 = new THREE.SphereGeometry(
                    r, // radius — 球体半径，默认为1
                    32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                    16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                    0, // phiStart — 指定水平（经线）起始角度，默认值为0
                    Math.PI * 2, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                    0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                    Math.PI // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
                );

                // this.a1 = new ThreeBSP(sphere1);

                if (vh === 'v') {
                    this.a2 = new ThreeBSP(sphere1);
                } else {
                    this.a1 = new ThreeBSP(sphere1);
                }
            }
        },
        // 配置以水平视场角为地基进行的裁剪
        initContentOgt1(coordinate) {
            let far = coordinate.farDistance,
                near = coordinate.nearDistance,
                vt = coordinate.fovVTop,
                vb = coordinate.fovVBottom;

            if (vt >= 90) vt = 89.9
            if (vb >= 90) vb = 89.9

            let r = Math.cos(THREE.MathUtils.degToRad(vt)) * far,
                h = Math.sin(THREE.MathUtils.degToRad(vt)) * far,
                r1 = Math.cos(THREE.MathUtils.degToRad(vb)) * far,
                h1 = Math.sin(THREE.MathUtils.degToRad(vb)) * far

            // 上方圆锥
            const cone1 = new THREE.ConeGeometry(
                r, // radius — 圆锥底部的半径，默认值为1
                h, // height — 圆锥的高度，默认值为1
                32, // radialSegments — 圆锥侧面周围的分段数，默认为32
                1, // heightSegments — 圆锥侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                2 * Math.PI, // thetaLength — 圆锥底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆锥
            );

            cone1.translate(0, -h / 2, 0);
            cone1.rotateX(Math.PI * 1);

            // 下方圆锥
            const cone2 = new THREE.ConeGeometry(
                r1, // radius — 圆锥底部的半径，默认值为1
                h1, // height — 圆锥的高度，默认值为1
                32, // radialSegments — 圆锥侧面周围的分段数，默认为32
                1, // heightSegments — 圆锥侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                2 * Math.PI, // thetaLength — 圆锥底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆锥
            );
            cone2.translate(0, -h1 / 2, 0);


            const circle1 = new THREE.CircleGeometry(r, 32);
            circle1.rotateX(Math.PI * 0.5);
            circle1.translate(0, h, 0);

            const circle2 = new THREE.CircleGeometry(r1, 32);
            circle2.rotateX(Math.PI * 0.5);
            circle2.translate(0, -h1, 0);


            if (near > 0) {
                const sphere1 = new THREE.SphereGeometry(
                    near, // radius — 球体半径，默认为1
                    32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                    16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                    0, // phiStart — 指定水平（经线）起始角度，默认值为0
                    Math.PI * 2, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                    0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                    Math.PI // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
                );
                this.z1 = new ThreeBSP(sphere1);
            }


            this.x1 = new ThreeBSP(circle1); // up
            this.y1 = new ThreeBSP(cone1);
            this.x2 = new ThreeBSP(circle2); // down
            this.y2 = new ThreeBSP(cone2);
        },
        // 配置以垂直视场角为地基进行的裁剪
        initContentOgt2(coordinate) {
            let far = coordinate.farDistance,
                near = coordinate.nearDistance,
                hl = coordinate.fovHLeft,
                hr = coordinate.fovHRight;

            if (hl >= 90) hl = 89.9
            if (hr >= 90) hr = 89.9

            let r = Math.cos(THREE.MathUtils.degToRad(hl)) * far,
                h = Math.sin(THREE.MathUtils.degToRad(hl)) * far,
                r1 = Math.cos(THREE.MathUtils.degToRad(hr)) * far,
                h1 = Math.sin(THREE.MathUtils.degToRad(hr)) * far;

            const cone1 = new THREE.ConeGeometry(
                r, // radius — 圆锥底部的半径，默认值为1
                h, // height — 圆锥的高度，默认值为1
                32, // radialSegments — 圆锥侧面周围的分段数，默认为32
                1, // heightSegments — 圆锥侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                2 * Math.PI, // thetaLength — 圆锥底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆锥
            );

            cone1.translate(0, -h / 2, 0);
            cone1.rotateX(Math.PI * 1);
            cone1.rotateZ(Math.PI * -0.5);

            const cone2 = new THREE.ConeGeometry(
                r1, // radius — 圆锥底部的半径，默认值为1
                h1, // height — 圆锥的高度，默认值为1
                32, // radialSegments — 圆锥侧面周围的分段数，默认为32
                1, // heightSegments — 圆锥侧面沿着其高度的分段数，默认值为1
                false, // openEnded — 一个Boolean值，指明该圆锥的底面是开放的还是封顶的。默认值为false，即其底面默认是封顶的
                0, // thetaStart — 第一个分段的起始角度，默认为0
                2 * Math.PI, // thetaLength — 圆锥底面圆扇区的中心角，通常被称为“θ”（西塔）。默认值是2*Pi，这使其成为一个完整的圆锥
            );
            cone2.translate(0, -h1 / 2, 0);
            cone2.rotateZ(Math.PI * -0.5);



            const circle01 = new THREE.CircleGeometry(r, 32);
            circle01.rotateX(Math.PI * 0.5);
            circle01.translate(0, h, 0);
            circle01.rotateZ(Math.PI * -0.5);

            const circle02 = new THREE.CircleGeometry(r1, 32);
            circle02.rotateX(Math.PI * 0.5);
            circle02.translate(0, -h1, 0);
            circle02.rotateZ(Math.PI * -0.5);


            if (near > 0) {
                const sphere1 = new THREE.SphereGeometry(
                    near, // radius — 球体半径，默认为1
                    32, // widthSegments — 水平分段数（沿着经线分段），最小值为3，默认值为32
                    16, // heightSegments — 垂直分段数（沿着纬线分段），最小值为2，默认值为16
                    0, // phiStart — 指定水平（经线）起始角度，默认值为0
                    Math.PI * 2, // phiLength — 指定水平（经线）扫描角度的大小，默认值为 Math.PI * 2
                    0, // thetaStart — 指定垂直（纬线）起始角度，默认值为0
                    Math.PI // thetaLength — 指定垂直（纬线）扫描角度大小，默认值为 Math.PI
                );
                this.z2 = new ThreeBSP(sphere1);
            }


            this.v1 = new ThreeBSP(circle01); // left
            this.w1 = new ThreeBSP(cone1);
            this.v2 = new ThreeBSP(circle02); // right
            this.w2 = new ThreeBSP(cone2);
        },
        initBSP(onlyClear = false) {
            const obj = this.scene.getObjectByName("cube");
            if (obj) {
                this.scene.remove(obj);
                this.clearCache(obj);
            }

            if (!!onlyClear) {
                return
            }

            const sensor = this.scene.getObjectByName("sensor");
            if (sensor) {
                this.scene.remove(sensor);
                this.clearCache(sensor);
            }

            showFullScreenLoading();

            setTimeout(() => {
                if (this.type === 1) {
                    if (this.cameraSensor) {
                        this.scene.add(this.cameraSensor);
                    } else {
                        this.initSensor({ x: 0, y: 0, z: 0 }, "camera");
                    }
                } else if (this.type === 2) {
                    if (this.ogt) {
                        this.scene.add(this.ogt);
                    } else {
                        this.initSensor({ x: 0, y: 0, z: 0 }, "ogt");
                    }
                } else if (this.type === 3) {
                    if (this.lidar) {
                        this.scene.add(this.lidar);
                    } else {
                        this.initSensor({ x: 0, y: 0, z: 0 }, "lidar");
                    }
                } else if (this.type === 4) {
                    if (this.gps) {
                        this.scene.add(this.gps);
                    } else {
                        this.initSensor({ x: 0, y: 0, z: 0 }, "gps");
                    }
                }
            }, 0)

            setTimeout(() => {
                // 解决bsp内存溢出后没法去掉loading
                let timer = setTimeout(() => {
                    clearTimeout(timer);
                    timer = null;

                    tryHideFullScreenLoading();
                }, 30000)

                this.initSensorBSP();

                clearTimeout(timer);
                timer = null;

                tryHideFullScreenLoading();
            }, 300)
        },
        initSensorBSP() {
            // let sensorId = this.configList[type][index].sensorId;

            // if (!this.bsp[type][sensorId]) {
            // let coordinate = this.allSensor[type].find(
            //     (i) => i.id === sensorId
            // );

            // if (!coordinate) {
            //     coordinate = {
            //         farDistance: 60,
            //         nearDistance: 0,
            //         fovH: 60,
            //         fovV: 60,
            //         fovHLeft: 60,
            //         fovVTop: 60,
            //         fovHRight: 60,
            //         fovVBottom: 60,
            //     };
            // } { f: 0, n: 0, h: 0, v: 0 }  { f: 0, n: 0, hl: 0, hr: 0, vt: 0, vb: 0 },


            const obj = this.scene.getObjectByName("cube");
            if (obj) {
                this.scene.remove(obj);
                this.clearCache(obj);
            }


            let coordinate = {};

            // console.log(this.type);
            // console.log(this.coordinate);
            // console.log(this.coordinateA);

            if (this.type != 2) {
                if (this.coordinate.f <= 0 || this.coordinate.n < 0 || this.coordinate.f <= this.coordinate.n
                    || this.coordinate.h <= 0 || this.coordinate.v <= 0) {
                    tryHideFullScreenLoading();
                    return;
                }

                coordinate = {
                    farDistance: this.coordinate.f / 100,
                    nearDistance: this.coordinate.n / 100,
                    fovH: this.coordinate.h,
                    fovV: this.coordinate.v,
                }


            } else {
                if (this.coordinateA.f <= 0 || this.coordinateA.n < 0 || this.coordinateA.f <= this.coordinateA.n
                    || (this.coordinateA.hl + this.coordinateA.hr <= 0) || (this.coordinateA.vt + this.coordinateA.vb <= 0)) {
                    tryHideFullScreenLoading();
                    return;
                }

                coordinate = {
                    farDistance: this.coordinateA.f / 100,
                    nearDistance: this.coordinateA.n / 100,
                    fovHLeft: this.coordinateA.hl == 0 ? 1 : this.coordinateA.hl,
                    fovHRight: this.coordinateA.hr == 0 ? 1 : this.coordinateA.hr,
                    fovVTop: this.coordinateA.vt == 0 ? 1 : this.coordinateA.vt,
                    fovVBottom: this.coordinateA.vb == 0 ? 1 : this.coordinateA.vb,
                }
            }

            // console.log(coordinate)

            let color = null;

            if (this.type === 1) {
                color = 0x0000ff;
            } else if (this.type === 2) {
                color = 0x008000;
            } else if (this.type === 3) {
                color = 0xff4500;
            } else {
                color = 0x0000ff;
            }

            // let m = new THREE.MeshPhongMaterial({ emissive: color, color: 0x4c4c4c, wireframe: true, transparent: true, opacity: 0.3, side: THREE.DoubleSide });
            // let m = new THREE.MeshPhongMaterial({ emissive: color, color: 0x4c4c4c, wireframe: true,  side: THREE.DoubleSide });
            let m = new THREE.MeshPhongMaterial({ emissive: color, color: 0x4c4c4c, transparent: true, opacity: 0.3, side: THREE.DoubleSide });
            // let m = new THREE.MeshPhongMaterial({ emissive: color, color: 0x4c4c4c,side: THREE.DoubleSide });


            if (this.type != 2) {
                this.toCube(coordinate, m);
            } else {
                this.toCubeOgt(coordinate, m);
            }

            // this.bsp[type][sensorId] = this.cube;
            // } else {
            //     this.cube = this.bsp[type][sensorId];
            // }

            let a = (100 / (this.scale / 0.6)) * 16.5;

            this.cube.scale.set(a, a, a);

            this.cube.name = this.geometryName || "cube";
            this.scene.add(this.cube);

            this.$emit('loadingDone', 'carDone');
        },
        toCube0(coordinate, m) {
            let { fovH, fovV, nearDistance } = coordinate;

            this.initContent0(coordinate, 'h', 'f');
            this.initContent0(coordinate, 'v', 'f');

            if (nearDistance > 0) {
                // 带盲区
                this.initContent0(coordinate, 'h', 'n');
                this.initContent0(coordinate, 'v', 'n');

                // 有至少一个方向是等于360的
                if (fovH >= 180 || fovV >= 180) {
                    if (fovH >= 180 && fovV < 180) {
                        if (fovV <= 90) {
                            this.cube = this.a2.subtract(this.b2).intersect(this.c2).subtract(this.x2.subtract(this.y2).intersect(this.z2)).toMesh(m);
                        } else {
                            this.cube = this.a2.subtract(this.b2.subtract(this.c2)).subtract(this.x2.subtract(this.y2.subtract(this.z2))).toMesh(m);
                        }
                    } else if (fovH < 180 && fovV >= 180) {
                        if (fovH <= 90) {
                            this.cube = this.a1.subtract(this.b1).subtract(this.c1).subtract(this.x1.subtract(this.y1).subtract(this.z1)).toMesh(m);
                        } else {
                            this.cube = this.a1.subtract(this.b1.intersect(this.c1)).subtract(this.x1.subtract(this.y1.intersect(this.z1))).toMesh(m);
                        }
                    } else if (fovH >= 180 && fovV >= 180) {
                        this.cube = this.a1.toMesh(m);
                    }
                } else {
                    if (fovH <= 90 && fovV <= 90) {
                        // 都小于90
                        this.cube = this.a1.subtract(this.b1).subtract(this.c1).intersect(this.a2.subtract(this.b2).intersect(this.c2))
                            .subtract(this.x1.subtract(this.y1).subtract(this.z1).intersect(this.x2.subtract(this.y2).intersect(this.z2))).toMesh(m);
                    } else if (fovH > 90 && fovV <= 90) {
                        // h大于90 v小于90
                        // this.cube = this.a1.subtract(this.b1.intersect(this.c1)).intersect(this.a2.subtract(this.b2).intersect(this.c2))
                        // .subtract(this.x1.subtract(this.y1.intersect(this.z1)).intersect(this.x2.subtract(this.y2).intersect(this.z2))).toMesh(m);
                        this.cube = this.a2.subtract(this.b2).intersect(this.c2).subtract(this.x2.subtract(this.y2).intersect(this.z2)).toMesh(m);
                    } else if (fovH <= 90 && fovV > 90) {
                        // h小于90 v大于90
                        // this.cube = this.a1.subtract(this.b1).subtract(this.c1).intersect(this.a2.subtract(this.b2.subtract(this.c2)))
                        //     .subtract(this.x1.subtract(this.y1).subtract(this.z1).intersect(this.x2.subtract(this.y2.subtract(this.z2)))).toMesh(m);
                        this.cube = this.a1.subtract(this.b1).subtract(this.c1).subtract(this.x1.subtract(this.y1).subtract(this.z1)).toMesh(m);
                    } else if (fovH > 90 && fovV > 90) {
                        // 都大于90
                        this.cube = this.a1.subtract(this.b1.intersect(this.c1)).intersect(this.a2.subtract(this.b2.subtract(this.c2)))
                            .subtract(this.x1.subtract(this.y1.intersect(this.z1)).intersect(this.x2.subtract(this.y2.subtract(this.z2)))).toMesh(m);
                    }
                }
            } else {
                // 有至少一个方向是等于360的
                if (fovH >= 180 || fovV >= 180) {
                    if (fovH >= 180 && fovV < 180) {
                        if (fovV <= 90) {
                            this.cube = this.a2.subtract(this.b2).intersect(this.c2).toMesh(m);
                        } else {
                            this.cube = this.a2.subtract(this.b2.subtract(this.c2)).toMesh(m);
                        }
                    } else if (fovH < 180 && fovV >= 180) {
                        if (fovH <= 90) {
                            this.cube = this.a1.subtract(this.b1).subtract(this.c1).toMesh(m);
                        } else {
                            this.cube = this.a1.subtract(this.b1.intersect(this.c1)).toMesh(m);
                        }
                    } else if (fovH >= 180 && fovV >= 180) {
                        this.cube = this.a1.toMesh(m);
                    }
                } else {
                    if (fovH <= 90 && fovV <= 90) {
                        // 都小于90
                        this.cube = this.a1.subtract(this.b1).subtract(this.c1).intersect(this.a2.subtract(this.b2).intersect(this.c2)).toMesh(m);
                    } else if (fovH > 90 && fovV <= 90) {
                        // h大于90 v小于90
                        // this.cube = this.a1.subtract(this.b1.intersect(this.c1)).intersect(this.a2.subtract(this.b2).intersect(this.c2)).toMesh(m);
                        this.cube = this.a2.subtract(this.b2).intersect(this.c2).toMesh(m);
                    } else if (fovH <= 90 && fovV > 90) {
                        // h小于90 v大于90
                        // this.cube = this.a1.subtract(this.b1).subtract(this.c1).intersect(this.a2.subtract(this.b2.subtract(this.c2))).toMesh(m);
                        this.cube = this.a1.subtract(this.b1).subtract(this.c1).toMesh(m);
                    } else if (fovH > 90 && fovV > 90) {
                        // 都大于90
                        this.cube = this.a1.subtract(this.b1.intersect(this.c1)).intersect(this.a2.subtract(this.b2.subtract(this.c2))).toMesh(m);
                    }
                }
            }


            this.a1 = null;
            this.b1 = null;
            this.c1 = null;
            this.d1 = null;
            this.a2 = null;
            this.b2 = null;
            this.c2 = null;
            this.d2 = null;
            this.e1 = null;
            this.x1 = null;
            this.y1 = null;
            this.z1 = null;
            this.w1 = null;
            this.x2 = null;
            this.y2 = null;
            this.z2 = null;
            this.w2 = null;
        },
        toCube(coordinate, m) {
            let { fovH, fovV, nearDistance } = coordinate;

            // this.initContent0(coordinate, 'h', 'f');
            // this.initContent0(coordinate, 'v', 'f');

            // this.initContent01(coordinate);


            // 垂直小于等于180
            if (fovV <= 180) {
                // 以水平为地基进行裁剪
                this.initContent0(coordinate, 'h', 'f');
                this.initContent01(coordinate);

                // 水平小于等于180
                if (fovH <= 180) {
                    // 带盲区 
                    if (nearDistance > 0) {
                        this.cube = this.a1.subtract(this.b1).subtract(this.c1)
                            .subtract(this.x1).subtract(this.y1).intersect(this.x2).subtract(this.y2).subtract(this.z1)
                            .toMesh(m);
                    } else {
                        this.cube = this.a1.subtract(this.b1).subtract(this.c1)
                            .subtract(this.x1).subtract(this.y1).intersect(this.x2).subtract(this.y2)
                            .toMesh(m);
                    }
                } else if (fovH > 180 && fovH < 360) {
                    // 180-360之间
                    if (nearDistance > 0) {
                        this.cube = this.a1.subtract(this.b1.intersect(this.c1))
                            .subtract(this.x1).subtract(this.y1).subtract(this.y2).intersect(this.x2).subtract(this.z1)
                            .toMesh(m);
                    } else {
                        this.cube = this.a1.subtract(this.b1.intersect(this.c1))
                            .subtract(this.x1).subtract(this.y1).subtract(this.y2).intersect(this.x2)
                            .toMesh(m);
                    }
                } else {
                    // 大于等于360
                    if (nearDistance > 0) {
                        this.cube = this.a1
                            .subtract(this.x1).subtract(this.y1).subtract(this.y2).intersect(this.x2).subtract(this.z1)
                            .toMesh(m);
                    } else {
                        this.cube = this.a1
                            .subtract(this.x1).subtract(this.y1).subtract(this.y2).intersect(this.x2)
                            .toMesh(m);
                    }
                }
            } else if (fovV > 180 && fovV < 360) { // 垂直 180-360之间
                // 以垂直为地基进行裁剪
                this.initContent0(coordinate, 'v', 'f');
                this.initContent02(coordinate);

                // 水平小于等于180
                if (fovH <= 180) {
                    // 带盲区 
                    if (nearDistance > 0) {
                        this.cube = this.a2.subtract(this.b2.subtract(this.c2))
                            .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2).subtract(this.z2)
                            .toMesh(m);
                    } else {
                        this.cube = this.a2.subtract(this.b2.subtract(this.c2))
                            .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2)
                            .toMesh(m);
                    }
                } else if (fovH > 180 && fovH < 360) { // 水平大于180小于360
                    // 以水平为地基进行裁剪
                    this.initContent0(coordinate, 'h', 'f');
                    this.initContent01(coordinate);

                    if (nearDistance > 0) {
                        this.cube = this.a1.subtract(this.b1.intersect(this.c1))
                            .union(this.a2.subtract(this.b2.subtract(this.c2))).subtract(this.z1)
                            .toMesh(m);
                    } else {
                        this.cube = this.a1.subtract(this.b1.intersect(this.c1))
                            .union(this.a2.subtract(this.b2.subtract(this.c2)))
                            .toMesh(m);
                    }
                } else { // 水平大于等于360
                    // 以水平为地基进行裁剪
                    this.initContent0(coordinate, 'h', 'f');
                    this.initContent01(coordinate);

                    if (nearDistance > 0) {
                        this.cube = this.a1.subtract(this.z1).toMesh(m);
                    } else {
                        this.cube = this.a1.toMesh(m);
                    }
                }
            } else { // 垂直大于等于360
                // 以垂直为地基进行裁剪
                this.initContent0(coordinate, 'v', 'f');
                this.initContent02(coordinate);

                if (fovH < 180) {
                    // 带盲区 
                    if (nearDistance > 0) {
                        this.cube = this.a2
                            .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2).subtract(this.z2)
                            .toMesh(m);
                    } else {
                        this.cube = this.a2
                            .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2)
                            .toMesh(m);
                    }
                } else {
                    if (nearDistance > 0) {
                        this.cube = this.a2.subtract(this.z2).toMesh(m);
                    } else {
                        this.cube = this.a2.toMesh(m);
                    }
                }
            }





            // 水平小于等于180
            /* if (fovH <= 180) {
                // 带盲区 
                if (nearDistance > 0) {
                    this.cube = this.a1.subtract(this.b1).subtract(this.c1)
                        .subtract(this.x1).subtract(this.y1).intersect(this.x2).subtract(this.y2).subtract(this.z1)
                        .toMesh(m);
                } else {
                    this.cube = this.a1.subtract(this.b1).subtract(this.c1)
                        .subtract(this.x1).subtract(this.y1).intersect(this.x2).subtract(this.y2)
                        .toMesh(m);
                }
            } else if (fovH > 180 && fovH < 360) {
                // 180-360之间
                if (nearDistance > 0) {
                    this.cube = this.a1.subtract(this.b1.intersect(this.c1))
                        .subtract(this.x1).subtract(this.y1).subtract(this.y2).intersect(this.x2).subtract(this.z1)
                        .toMesh(m);
                } else {
                    this.cube = this.a1.subtract(this.b1.intersect(this.c1))
                        .subtract(this.x1).subtract(this.y1).subtract(this.y2).intersect(this.x2)
                        .toMesh(m);
                }
            } else {
                // 大于等于360
                if (nearDistance > 0) {
                    this.cube = this.a1
                        .subtract(this.x1).subtract(this.y1).subtract(this.y2).intersect(this.x2).subtract(this.z1)
                        .toMesh(m);
                } else {
                    this.cube = this.a1
                        .subtract(this.x1).subtract(this.y1).subtract(this.y2).intersect(this.x2)
                        .toMesh(m);
                }
            } */


            this.a1 = null;
            this.b1 = null;
            this.c1 = null;
            this.d1 = null;
            this.a2 = null;
            this.b2 = null;
            this.c2 = null;
            this.d2 = null;
            this.e1 = null;
            this.x1 = null;
            this.y1 = null;
            this.z1 = null;
            this.v1 = null;
            this.w1 = null;
            this.x2 = null;
            this.y2 = null;
            this.z2 = null;
            this.v2 = null;
            this.w2 = null;
        },
        toCubeOgt0(coordinate, m) {
            let { fovHLeft, fovHRight, fovVTop, fovVBottom, nearDistance } = coordinate;

            this.initContentOgt(coordinate, 'h', 'f');
            this.initContentOgt(coordinate, 'v', 'f');

            if (nearDistance > 0) {
                // 带盲区
                this.initContentOgt(coordinate, 'h', 'n');
                this.initContentOgt(coordinate, 'v', 'n');

                // 有至少一个方向是大于360的
                if ((fovHLeft + fovHRight >= 360) || (fovVTop + fovVBottom >= 360)) {
                    if ((fovHLeft + fovHRight >= 360) && (fovVTop + fovVBottom < 360)) {
                        if (fovVTop + fovVBottom <= 180) {
                            this.cube = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
                                .subtract(this.x2.intersect(this.w2).subtract(this.y2).intersect(this.z2))
                                .toMesh(m);
                        } else {
                            this.cube = this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .subtract(this.x2.intersect(this.w2).subtract(this.y2.subtract(this.z2)))
                                .toMesh(m);
                        }
                    } else if ((fovHLeft + fovHRight < 360) && (fovVTop + fovVBottom >= 360)) {
                        if (fovHLeft + fovHRight <= 180) {
                            this.cube = this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1)
                                .subtract(this.x1.intersect(this.w1).subtract(this.y1).subtract(this.z1))
                                .toMesh(m);
                        } else {
                            this.cube = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1))
                                .subtract(this.x1.intersect(this.w1).subtract(this.y1.intersect(this.z1)))
                                .toMesh(m);
                        }
                    } else if ((fovHLeft + fovHRight >= 360) && (fovVTop + fovVBottom >= 360)) {
                        this.cube = this.a1.intersect(this.d1).toMesh(m);
                    }
                } else {
                    // 不带盲区
                    if ((fovHLeft + fovHRight <= 180) && (fovVTop + fovVBottom <= 180)) {
                        // 相加都小于180
                        this.cube = this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1).intersect(this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2))
                            .subtract(this.x1.intersect(this.w1).subtract(this.y1).subtract(this.z1).intersect(this.x2.intersect(this.w2).subtract(this.y2).intersect(this.z2)))
                            .toMesh(m);
                    } else if ((fovHLeft + fovHRight > 180) && (fovVTop + fovVBottom <= 180)) {
                        // 左右相加大于180  上下相加小于180
                        this.cube = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)).intersect(this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2))
                            .subtract(this.x1.intersect(this.w1).subtract(this.y1.intersect(this.z1)).intersect(this.x2.intersect(this.w2).subtract(this.y2).intersect(this.z2)))
                            .toMesh(m);
                    } else if ((fovHLeft + fovHRight <= 180) && (fovVTop + fovVBottom > 180)) {
                        // 左右相加小于180  上下相加大于180
                        this.cube = this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1).intersect(this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2)))
                            .subtract(this.x1.intersect(this.w1).subtract(this.y1).subtract(this.z1).intersect(this.x2.intersect(this.w2).subtract(this.y2.subtract(this.z2))))
                            .toMesh(m);
                    } else if ((fovHLeft + fovHRight > 180) && (fovVTop + fovVBottom > 180)) {
                        // 相加都大于180
                        this.cube = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)).intersect(this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2)))
                            .subtract(this.x1.intersect(this.w1).subtract(this.y1.intersect(this.z1)).intersect(this.x2.intersect(this.w2).subtract(this.y2.subtract(this.z2))))
                            .toMesh(m);
                    }
                }
            } else {
                // 有至少一个方向是大于360的
                if ((fovHLeft + fovHRight >= 360) || (fovVTop + fovVBottom >= 360)) {
                    if ((fovHLeft + fovHRight >= 360) && (fovVTop + fovVBottom < 360)) {
                        if (fovVTop + fovVBottom <= 180) {
                            this.cube = this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2).toMesh(m);
                        } else {
                            this.cube = this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2)).toMesh(m);
                        }
                    } else if ((fovHLeft + fovHRight < 360) && (fovVTop + fovVBottom >= 360)) {
                        if (fovHLeft + fovHRight <= 180) {
                            this.cube = this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1).toMesh(m);
                        } else {
                            this.cube = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)).toMesh(m);
                        }
                    } else if ((fovHLeft + fovHRight >= 360) && (fovVTop + fovVBottom >= 360)) {
                        this.cube = this.a1.intersect(this.d1).toMesh(m);
                    }
                } else {
                    if ((fovHLeft + fovHRight <= 180) && (fovVTop + fovVBottom <= 180)) {
                        // 相加都小于180
                        this.cube = this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1).intersect(this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)).toMesh(m);
                    } else if ((fovHLeft + fovHRight > 180) && (fovVTop + fovVBottom <= 180)) {
                        // 左右相加大于180  上下相加小于180
                        this.cube = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)).intersect(this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)).toMesh(m);
                    } else if ((fovHLeft + fovHRight <= 180) && (fovVTop + fovVBottom > 180)) {
                        // 左右相加小于180  上下相加大于180
                        this.cube = this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1).intersect(this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))).toMesh(m);
                    } else if ((fovHLeft + fovHRight > 180) && (fovVTop + fovVBottom > 180)) {
                        // 相加都大于180
                        this.cube = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)).intersect(this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))).toMesh(m);
                    }
                }
            }

            this.a1 = null;
            this.b1 = null;
            this.c1 = null;
            this.d1 = null;
            this.a2 = null;
            this.b2 = null;
            this.c2 = null;
            this.d2 = null;
            this.e1 = null;
            this.x1 = null;
            this.y1 = null;
            this.z1 = null;
            this.w1 = null;
            this.x2 = null;
            this.y2 = null;
            this.z2 = null;
            this.w2 = null;
        },
        toCubeOgt(coordinate, m) {
            let { fovHLeft, fovHRight, fovVTop, fovVBottom, nearDistance } = coordinate;

            if (fovHLeft + fovHRight > 360) {
                coordinate.fovHLeft = 180
                coordinate.fovHRight = 180
            }

            if (fovVTop + fovVBottom > 360) {
                coordinate.fovVTop = 180
                coordinate.fovVBottom = 180
            }

            this.initContentOgt(coordinate, 'h', 'f');
            this.initContentOgt(coordinate, 'v', 'f');

            this.initContentOgt1(coordinate);
            this.initContentOgt2(coordinate);


            let cube = "";


            if (fovVTop <= 90 && fovVBottom <= 90) { // 垂直都不大于90
                // 水平小于等于180
                if (fovHLeft + fovHRight <= 180) {
                    // 带盲区 
                    if (nearDistance > 0) {
                        this.cube = this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1)
                            .subtract(this.x1).subtract(this.y1).intersect(this.x2).subtract(this.y2).subtract(this.z1)
                            .toMesh(m);
                    } else {
                        this.cube = this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1)
                            .subtract(this.x1).subtract(this.y1).intersect(this.x2).subtract(this.y2)
                            .toMesh(m);
                    }
                    // 180-360之间
                } else if ((fovHLeft + fovHRight > 180) && (fovHLeft + fovHRight < 360)) {
                    if (nearDistance > 0) {
                        this.cube = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1))
                            .subtract(this.x1).subtract(this.y1).subtract(this.y2).intersect(this.x2).subtract(this.z1)
                            .toMesh(m);
                    } else {
                        this.cube = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1))
                            .subtract(this.x1).subtract(this.y1).subtract(this.y2).intersect(this.x2)
                            .toMesh(m);
                    }
                } else {
                    // 大于等于360
                    if (nearDistance > 0) {
                        this.cube = this.a1
                            .subtract(this.x1).subtract(this.y1).intersect(this.x2).subtract(this.y2).subtract(this.z1)
                            .toMesh(m);
                    } else {
                        this.cube = this.a1
                            .subtract(this.x1).subtract(this.y1).intersect(this.x2).subtract(this.y2)
                            .toMesh(m);
                    }
                }
            } else if (fovVTop > 90 && fovVBottom <= 90) { // 垂直 上大于90 下不大于90
                if (fovVTop + fovVBottom <= 180) { // 垂直相加不大于180
                    if (fovHLeft <= 90 && fovHRight <= 90) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
                                .subtract(this.v1).subtract(this.w1)
                                .intersect(this.v2).subtract(this.w2)`
                    } else if (fovHLeft > 90 && fovHLeft <= 180 && fovHRight <= 90) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
                                .intersect(this.v2).subtract(this.w2)
                                .union(this.d1.subtract(this.b1).intersect(this.e1))
                                .intersect(this.x2).subtract(this.y2)`
                    } else if (fovHLeft > 180 && fovHRight <= 90 && (fovHLeft + fovHRight < 360)) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
                                .intersect(this.v2).subtract(this.w2)
                                .union(this.d1.subtract(this.b1.subtract(this.e1)))
                                .intersect(this.x2).subtract(this.y2)`
                    } else if (fovHRight > 90 && fovHRight <= 180 && fovHLeft <= 90) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
                                .subtract(this.v1).subtract(this.w1)
                                .union(this.a1.subtract(this.c1).subtract(this.e1))
                                .intersect(this.x2).subtract(this.y2)`
                    } else if (fovHRight > 180 && fovHLeft <= 90 && (fovHLeft + fovHRight < 360)) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
                                .subtract(this.v1).subtract(this.w1)
                                .union(this.a1.subtract(this.c1.intersect(this.e1)))
                                .intersect(this.x2).subtract(this.y2)`
                    } else if (fovHLeft > 90 && fovHRight > 90 && (fovHLeft + fovHRight < 360)) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
                                .union(this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)))
                                .intersect(this.x2).subtract(this.y2)`
                    } else {  // 水平相加 不小于360
                        cube = `this.a1
                                .intersect(this.x2).subtract(this.y2)`
                    }
                } else if ((fovVTop + fovVBottom > 180) && (fovVTop + fovVBottom < 360)) { // 垂直相加 180-360
                    if (fovHLeft <= 90 && fovHRight <= 90) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2)`
                    } else if (fovHLeft > 90 && fovHLeft <= 180 && fovHRight <= 90) { // 水平相加 180-360
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .intersect(this.v2).subtract(this.w2)
                                .union(this.d1.subtract(this.b1).intersect(this.e1))
                                .intersect(this.x2).subtract(this.y2)`
                    } else if (fovHLeft > 180 && fovHRight <= 90 && (fovHLeft + fovHRight < 360)) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .intersect(this.v2).subtract(this.w2)
                                .union(this.d1.subtract(this.b1.subtract(this.e1)))
                                .intersect(this.x2).subtract(this.y2)`
                    } else if (fovHRight > 90 && fovHRight <= 180 && fovHLeft <= 90) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .subtract(this.v1).subtract(this.w1)
                                .union(this.a1.subtract(this.c1).subtract(this.e1))
                                .intersect(this.x2).subtract(this.y2)`
                    } else if (fovHRight > 180 && fovHLeft <= 90 && (fovHLeft + fovHRight < 360)) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .subtract(this.v1).subtract(this.w1)
                                .union(this.a1.subtract(this.c1.intersect(this.e1)))
                                .intersect(this.x2).subtract(this.y2)`
                    } else if (fovHLeft > 90 && fovHRight > 90 && (fovHLeft + fovHRight < 360)) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .union(this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)))
                                .intersect(this.x2).subtract(this.y2)`
                    } else {  // 水平相加 不小于360
                        cube = `this.a1
                                .intersect(this.x2).subtract(this.y2)`
                    }
                } else { // 垂直相加 >360
                    if(fovHLeft + fovHRight < 180) { // 水平相加小于180
                        if(fovHLeft <= 90 && fovHRight <= 90) { // 都小于等于90
                             cube = `this.a2
                                .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2)`
                        }else if(fovHLeft > 90) { // 左大于90 右小于90
                            cube = `this.a2
                                .intersect(this.v2).subtract(this.w2)`
                        }else { // 左小于90 右大于90
                            cube = `this.a2
                                .subtract(this.v1).subtract(this.w1)`
                        }
                    }else { // 水平相加>=180
                        cube = `this.a2`
                    }
                }
            } else if (fovVTop <= 90 && fovVBottom > 90) { // 垂直 上不大于90 下大于90
                if (fovVTop + fovVBottom <= 180) { // 垂直相加不大于180
                    if (fovHLeft <= 90 && fovHRight <= 90) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
                                .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2)`
                    } else if (fovHLeft > 90 && fovHLeft <= 180 && fovHRight <= 90) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
                                .intersect(this.v2).subtract(this.w2)
                                .union(this.d1.subtract(this.b1).intersect(this.e1))
                                .subtract(this.x1).subtract(this.y1)`
                    } else if (fovHLeft > 180 && fovHRight <= 90 && (fovHLeft + fovHRight < 360)) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
                                .intersect(this.v2).subtract(this.w2)
                                .union(this.d1.subtract(this.b1.subtract(this.e1)))
                                .subtract(this.x1).subtract(this.y1)`
                    } else if (fovHRight > 90 && fovHRight <= 180 && fovHLeft <= 90) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
                                .subtract(this.v1).subtract(this.w1)
                                .union(this.a1.subtract(this.c1).subtract(this.e1))
                                .subtract(this.x1).subtract(this.y1)`
                    } else if (fovHRight > 180 && fovHLeft <= 90 && (fovHLeft + fovHRight < 360)) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
                                .subtract(this.v1).subtract(this.w1)
                                .union(this.a1.subtract(this.c1.intersect(this.e1)))
                                .subtract(this.x1).subtract(this.y1)`
                    } else if (fovHLeft > 90 && fovHRight > 90 && (fovHLeft + fovHRight < 360)) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2).intersect(this.c2)
                                .union(this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)))
                                .subtract(this.x1).subtract(this.y1)`
                    } else {  // 水平相加 不小于360
                        cube = `this.a1
                                .subtract(this.x1).subtract(this.y1)`
                    }
                } else if ((fovVTop + fovVBottom > 180) && (fovVTop + fovVBottom < 360)) { // 垂直相加 180-360
                    if (fovHLeft <= 90 && fovHRight <= 90) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2)`
                    } else if (fovHLeft > 90 && fovHLeft <= 180 && fovHRight <= 90) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .intersect(this.v2).subtract(this.w2)
                                .union(this.d1.subtract(this.b1).intersect(this.e1))
                                .subtract(this.x1).subtract(this.y1)`
                    } else if (fovHLeft > 180 && fovHRight <= 90 && (fovHLeft + fovHRight < 360)) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .intersect(this.v2).subtract(this.w2)
                                .union(this.d1.subtract(this.b1.subtract(this.e1)))
                                .subtract(this.x1).subtract(this.y1)`
                    } else if (fovHRight > 90 && fovHRight <= 180 && fovHLeft <= 90) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .subtract(this.v1).subtract(this.w1)
                                .union(this.a1.subtract(this.c1).subtract(this.e1))
                                .subtract(this.x1).subtract(this.y1)`
                    } else if (fovHRight > 180 && fovHLeft <= 90 && (fovHLeft + fovHRight < 360)) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .subtract(this.v1).subtract(this.w1)
                                .union(this.a1.subtract(this.c1.intersect(this.e1)))
                                .subtract(this.x1).subtract(this.y1)`
                    } else if (fovHLeft > 90 && fovHRight > 90 && (fovHLeft + fovHRight < 360)) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .union(this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)))
                                .subtract(this.x1).subtract(this.y1)`
                    } else {  // 水平相加 不小于360
                        cube = `this.a1
                                .subtract(this.x1).subtract(this.y1)`
                    }
                } else { // 垂直相加 >360
                    if(fovHLeft + fovHRight < 180) { // 水平相加小于180
                        if(fovHLeft <= 90 && fovHRight <= 90) { // 都小于等于90
                             cube = `this.a2
                                .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2)`
                        }else if(fovHLeft > 90) { // 左大于90 右小于90
                            cube = `this.a2
                                .intersect(this.v2).subtract(this.w2)`
                        }else { // 左小于90 右大于90
                            cube = `this.a2
                                .subtract(this.v1).subtract(this.w1)`
                        }
                    }else { // 水平相加>=180
                        cube = `this.a2`
                    }
                }
            } else { // 垂直 都大于90
                if (fovVTop + fovVBottom < 360) { // 垂直相加 180-360
                    if (fovHLeft <= 90 && fovHRight <= 90) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2)`
                    } else if (fovHLeft > 90 && fovHLeft <= 180 && fovHRight <= 90) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .intersect(this.v2).subtract(this.w2)
                                .union(this.d1.subtract(this.b1).intersect(this.e1))`
                    } else if (fovHLeft > 180 && fovHRight <= 90 && (fovHLeft + fovHRight < 360)) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .intersect(this.v2).subtract(this.w2)
                                .union(this.d1.subtract(this.b1.subtract(this.e1)))`
                    } else if (fovHRight > 90 && fovHRight <= 180 && fovHLeft <= 90) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .subtract(this.v1).subtract(this.w1)
                                .union(this.a1.subtract(this.c1).subtract(this.e1))`
                    } else if (fovHRight > 180 && fovHLeft <= 90 && (fovHLeft + fovHRight < 360)) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .subtract(this.v1).subtract(this.w1)
                                .union(this.a1.subtract(this.c1.intersect(this.e1)))`
                    } else if (fovHLeft > 90 && fovHRight > 90 && (fovHLeft + fovHRight < 360)) {
                        cube = `this.a2.intersect(this.d2).subtract(this.b2.subtract(this.c2))
                                .union(this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1)))`
                    } else {  // 水平相加 不小于360
                        cube = `this.a1`
                    }
                } else { // 垂直相加 >360
                    if(fovHLeft + fovHRight < 180) { // 水平相加小于180
                        if(fovHLeft <= 90 && fovHRight <= 90) { // 都小于等于90
                             cube = `this.a2
                                .subtract(this.v1).subtract(this.w1).intersect(this.v2).subtract(this.w2)`
                        }else if(fovHLeft > 90) { // 左大于90 右小于90
                            cube = `this.a2
                                .intersect(this.v2).subtract(this.w2)`
                        }else { // 左小于90 右大于90
                            cube = `this.a2
                                .subtract(this.v1).subtract(this.w1)`
                        }
                    }else { // 水平相加>=180
                        cube = `this.a2`
                    }
                }
            }



            if (cube != "") {
                // 带盲区 
                if (nearDistance > 0) {
                    cube = cube + '.subtract(this.z2).toMesh(m)';
                } else {
                    cube = cube + '.toMesh(m)';
                }

                this.cube = eval(cube);
            }




            // // 水平小于等于180
            // if (fovHLeft + fovHRight <= 180) {
            //     // 带盲区 
            //     if (nearDistance > 0) {
            //         this.cube = this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1)
            //             .subtract(this.x1).subtract(this.y1).intersect(this.x2).subtract(this.y2).subtract(this.z1)
            //             .toMesh(m);
            //     } else {
            //         this.cube = this.a1.intersect(this.d1).subtract(this.b1).subtract(this.c1)
            //             .subtract(this.x1).subtract(this.y1).intersect(this.x2).subtract(this.y2)
            //             .toMesh(m);
            //     }
            //     // 180-360之间
            // } else if ((fovHLeft + fovHRight > 180) && (fovHLeft + fovHRight < 360)) {
            //     if (nearDistance > 0) {
            //         this.cube = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1))
            //             .subtract(this.x1).subtract(this.y1).subtract(this.y2).intersect(this.x2).subtract(this.z1)
            //             .toMesh(m);
            //     } else {
            //         this.cube = this.a1.intersect(this.d1).subtract(this.b1.intersect(this.c1))
            //             .subtract(this.x1).subtract(this.y1).subtract(this.y2).intersect(this.x2)
            //             .toMesh(m);
            //     }
            // } else {
            //     // 大于等于360
            //     if (nearDistance > 0) {
            //         this.cube = this.a1
            //             .subtract(this.x1).subtract(this.y1).intersect(this.x2).subtract(this.y2).subtract(this.z1)
            //             .toMesh(m);
            //     } else {
            //         this.cube = this.a1
            //             .subtract(this.x1).subtract(this.y1).intersect(this.x2).subtract(this.y2)
            //             .toMesh(m);
            //     }
            // }

            this.a1 = null;
            this.b1 = null;
            this.c1 = null;
            this.d1 = null;
            this.a2 = null;
            this.b2 = null;
            this.c2 = null;
            this.d2 = null;
            this.e1 = null;
            this.x1 = null;
            this.y1 = null;
            this.z1 = null;
            this.v1 = null;
            this.w1 = null;
            this.x2 = null;
            this.y2 = null;
            this.z2 = null;
            this.v2 = null;
            this.w2 = null;
        },
        // 初始化传感器
        initSensor(
            pos = { x: 0, y: 0, z: 0 },
            type = "camera",
            canMove = false
        ) {
            let Loader = new MTLLoader(); //材质文件加载器
            let loader = new OBJLoader(); //obj加载器
            let that = this;
            let mtlUrl = "";
            let objUrl = "";

            if (type === "camera") {
                mtlUrl = `${that.publicPath}sensor/camera/camera.mtl`;
                objUrl = `${that.publicPath}sensor/camera/camera.obj`;
            } else if (type === "ogt") {
                mtlUrl = `${that.publicPath}sensor/ogt/millimeter_wave_radar.mtl`;
                objUrl = `${that.publicPath}sensor/ogt/millimeter_wave_radar.obj`;
            } else if (type === "lidar") {
                mtlUrl = `${that.publicPath}sensor/lidar/LIDAR.mtl`;
                objUrl = `${that.publicPath}sensor/lidar/LIDAR.obj`;
            } else if (type === "gps") {
                mtlUrl = `${that.publicPath}sensor/gps/lidar.mtl`;
                objUrl = `${that.publicPath}sensor/gps/lidar.obj`;
            }

            this.$emit('loadingDone', 'carStart');

            if (type === "ogt") {
                // showFullScreenLoading();


                var loader1 = new GLTFLoader(); //创建一个FBX加载器

                loader1.load(
                    `${that.publicPath}sensor/ogt/ogt.glb`,
                    function (obj) {
                        that.$emit('loadingDone', 'carDone');

                        that.ogt = obj.scene;

                        that.cacheList.push(obj.scene);

                        let s = that.scale;

                        let scale = 0.1;
                        obj.scene.scale.set(scale, scale, scale);

                        obj.scene.position.set(pos.x, pos.y, pos.z);
                        obj.scene.name = "sensor";

                        that.sensor = obj.scene;

                        that.scene.add(that.sensor); //返回的组对象插入场景中
                    },
                    (xhr) => { },
                    (error) => {
                        that.$emit('loadingDone', 'carDone');

                        console.error(error);
                    }
                );

                return
            }

            Loader.load(
                mtlUrl,
                function (materials) {
                    loader.setMaterials(materials);
                    loader.load(objUrl, function (obj) {
                        // if (type === "ogt") {
                        //     tryHideFullScreenLoading();
                        // }

                        that.$emit('loadingDone', 'carDone');

                        if (type === "camera") {
                            that.cameraSensor = obj;
                        } else if (type === "ogt") {
                            that.ogt = obj;
                        } else if (type === "lidar") {
                            that.lidar = obj;
                        } else if (type === "gps") {
                            that.gps = obj;
                        }

                        that.cacheList.push(obj);
                        for (let i = 0; i < obj.children.length; i++) {
                            if (type === "camera") {
                                let scale = 0.8 * that.scale;
                                // obj.children[i].scale.set(scale, scale, scale);
                                obj.children[i].scale.set(0.4, 0.4, 0.4);
                            } else if (type === "ogt") {
                                let scale = 0.2 * that.scale;
                                obj.children[i].scale.set(scale, scale, scale);
                            } else if (type === "lidar") {
                                let scale = 0.03 * that.scale;
                                // obj.children[i].scale.set(scale, scale, scale);
                                obj.children[i].scale.set(0.06, 0.06, 0.06);
                            } else if (type === "gps") {
                                let scale = 40 * that.scale;
                                obj.children[i].scale.set(scale, scale, scale);
                            }
                        }
                        obj.position.set(pos.x, pos.y, pos.z);
                        obj.name = "sensor";

                        that.sensor = obj;

                        that.scene.add(that.sensor); //返回的组对象插入场景中
                    });
                },
                (xhr) => {
                    // console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
                },
                (error) => {
                    // if (type === "ogt") {
                    //     tryHideFullScreenLoading();
                    // }

                    that.$emit('loadingDone', 'carDone');

                    console.error(error);
                }
            );
        },
        // 初始化
        init() {
            this.initScene();
            this.initCamera();
            this.initRenderer();
            this.initLight();

            this.controls = new OrbitControls(
                this.camera,
                this.renderer.domElement
            ); //创建控件对象
            this.controls.minDistance = 30;
            this.controls.maxDistance = 18000;
            this.controls.update();
        },
        animate() {
            this.raf = requestAnimationFrame(this.animate);
            this.renderer.render(this.scene, this.camera);
            if (this.transformControls) {
                this.transformControls.update();
            }

            this.controls.update();
        },
        onWindowResize() {
            this.camera.aspect =
                this.container.clientWidth / this.container.clientHeight;
            this.camera.updateProjectionMatrix();
            this.renderer.setSize(
                this.container.clientWidth,
                this.container.clientHeight
            );
        },
        go() {
            this.container = document.getElementById(
                "containerThreeSensorModel"
            );
            this.init();
            this.animate();

            window.addEventListener("resize", this.onWindowResize);
        },
        removeScene() {
            this.clearScene();
        },
        clearCache(item) {
            if (item.geometry && item.geometry.dispose) item.geometry.dispose();
            if (item.material && item.material.dispose) item.material.dispose();
        },
        clearScene() {
            this.removeObj(this.scene);
        },
        removeObj(obj) {
            let arr = obj.children.filter((x) => x);
            arr.forEach((item) => {
                if (item.children.length) {
                    this.removeObj(item);
                } else {
                    this.clearCache(item);
                    item.clear();
                }
            }),
                obj.clear();
            arr = null;
        },
    },

    mounted() {
        this.go();
    },
    destroyed() {
        window.removeEventListener("resize", this.onWindowResize);
        cancelAnimationFrame(this.raf);

        if (this.renderer) {
            this.renderer.renderLists.dispose();
            this.renderer.dispose();
            this.renderer.forceContextLoss();
            this.renderer.domElement = null;
            this.renderer.content = null;
            this.renderer = null;
        }

        if (this.dragControls) {
            this.dragControls.deactivate();
            this.dragControls.dispose();
            this.dragControls = null;
        }

        if (this.controls) {
            this.controls.dispose();
            this.controls = null;
        }

        if (this.transformControls) {
            this.transformControls.detach();
            this.transformControls.dispose();
            this.transformControls = null;
        }

        if (this.cacheList.length > 0) {
            this.scene.remove(...this.cacheList);
            this.cacheList = [];
        }

        this.clearScene();

        this.scene = null;
        this.camera = null;
        this.light = null;
        this.geometryName = null;
        this.mesh = null;
        this.cube = null;
        this.container = null;
        this.car = null;
        this.cubeTexture = null;
        this.raf = null;

        this.bsp = null;
        this.a1 = null;
        this.b1 = null;
        this.c1 = null;
        this.d1 = null;
        this.a2 = null;
        this.b2 = null;
        this.c2 = null;
        this.d2 = null;
        this.e1 = null;
        this.e1 = null;
        this.x1 = null;
        this.y1 = null;
        this.z1 = null;
        this.v1 = null;
        this.w1 = null;
        this.x2 = null;
        this.y2 = null;
        this.z2 = null;
        this.v2 = null;
        this.w2 = null;

        THREE.Cache.clear();
    },
};
</script>

<style lang="less" scoped>
#containerThreeSensorModel {
    width: 100%;
    height: calc(100vh - 180px);
}
</style>
