Browse Source

车辆配置详情3d效果优化

zhangliang2 2 years ago
parent
commit
2b26cb58e9

File diff suppressed because it is too large
+ 0 - 0
public/font.json


BIN
src/assets/common/image/others/close.png


BIN
src/assets/common/image/others/open.png


+ 100 - 7
src/views/modelLibrary/common/coordinateAxes.js

@@ -1,8 +1,16 @@
 import * as THREE from 'three'
 import * as THREE from 'three'
+import {
+    FontLoader
+} from "three/examples/jsm/loaders/FontLoader.js"
+import {
+    TextGeometry
+} from "three/examples/jsm/geometries/TextGeometry.js"
+
+let publicPath = process.env.BASE_URL
 
 
 export default class CoordinateAxes extends THREE.Object3D {
 export default class CoordinateAxes extends THREE.Object3D {
     name = 'COORDINATE_AXES'
     name = 'COORDINATE_AXES'
-    AXIS_LENGTH = 300
+    AXIS_LENGTH = 150
     // follows right-hand coordinate system
     // follows right-hand coordinate system
     AXIS_COLOR_X = 0xff0000 // red
     AXIS_COLOR_X = 0xff0000 // red
     AXIS_COLOR_Y = 0x00ff00 // green
     AXIS_COLOR_Y = 0x00ff00 // green
@@ -22,11 +30,96 @@ export default class CoordinateAxes extends THREE.Object3D {
         this.add(arrowX, arrowY, arrowZ)
         this.add(arrowX, arrowY, arrowZ)
 
 
         // an additional box at the origin
         // an additional box at the origin
-        const sphere = new THREE.SphereGeometry(this.AXIS_LENGTH / 20)
-        const object = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({
-            color: 0xffff00
-        }))
-        const box = new THREE.BoxHelper(object, 0xffff00)
-        this.add(box)
+        // const sphere = new THREE.SphereGeometry(this.AXIS_LENGTH / 20)
+        // const object = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({
+        //     color: 0xffff00
+        // }))
+        // const box = new THREE.BoxHelper(object, 0xffff00)
+        // this.add(box)
+
+        let that = this
+
+        const loader = new FontLoader();
+        loader.load(
+            // 资源URL
+            `${publicPath}font.json`,
+            // onLoad回调
+            function (font) {
+                // do something with the font
+                // console.log(font);
+                const geometryX = new TextGeometry('X', {
+                    font: font,
+                    size: 40, // 字体大小
+                    height: 2, // 字体深度
+                    curveSegments: 12, // 曲线控制点数
+                    bevelEnabled: true, // 斜角
+                    bevelThickness: 0.1, // 斜角的深度
+                    bevelSize: 1, // 斜角的大小
+                    bevelSegments: 1 // 斜角段数
+                });
+
+                var matX = new THREE.MeshBasicMaterial({
+                    color: 0x0000ff,
+                    // opacity: 0.6,
+                    // shininess: 1,
+                    // transparent: true,
+                });
+                var meshX = new THREE.Mesh(geometryX, matX);
+                meshX.rotation.y = -Math.PI / 2
+                // meshX.rotation.z = Math.PI / 10
+                meshX.position.set(0, 0, 160);
+                that.add(meshX);
+
+                const geometryY = new TextGeometry('Y', {
+                    font: font,
+                    size: 34, // 字体大小
+                    height: 2, // 字体深度
+                    curveSegments: 12, // 曲线控制点数
+                    bevelEnabled: true, // 斜角
+                    bevelThickness: 0.1, // 斜角的深度
+                    bevelSize: 1, // 斜角的大小
+                    bevelSegments: 1 // 斜角段数
+                });
+
+                var matY = new THREE.MeshBasicMaterial({
+                    color: 0x00ff00,
+                });
+                var meshY = new THREE.Mesh(geometryY, matY);
+                meshY.rotation.y = Math.PI / 4.5
+                meshY.position.set(0, 160, 0);
+                that.add(meshY);
+
+                const geometryZ = new TextGeometry('Z', {
+                    font: font,
+                    size: 40, // 字体大小
+                    height: 2, // 字体深度
+                    curveSegments: 12, // 曲线控制点数
+                    bevelEnabled: true, // 斜角
+                    bevelThickness: 0.1, // 斜角的深度
+                    bevelSize: 1, // 斜角的大小
+                    bevelSegments: 1 // 斜角段数
+                });
+
+                var matZ = new THREE.MeshBasicMaterial({
+                    color: 0xff0000,
+                });
+                var meshZ = new THREE.Mesh(geometryZ, matZ);
+                // meshZ.rotation.y = Math.PI / 5
+                // meshZ.rotation.x = -Math.PI / 6
+                // meshZ.rotation.z = Math.PI / 6
+                meshZ.position.set(160, 0, 0);
+                that.add(meshZ);
+            },
+
+            // onProgress回调
+            function (xhr) {
+                // console.log((xhr.loaded / xhr.total * 100) + '% loaded');
+            },
+
+            // onError回调
+            function (err) {
+                console.log('An error happened');
+            }
+        );
     }
     }
 }
 }

+ 0 - 103
src/views/modelLibrary/common/coordinateAxesRenderer.js

@@ -1,103 +0,0 @@
-import * as THREE from 'three'
-import CoordinateAxes from './coordinateAxes'
-// import Renderer from '@/components/common/Renderer'
-
-/**
- * This renderer monitors the host renderer's camera, and keeps a coordinate axes
- * the same direction as host renderer's
- */
-export default class CoordinateAxesRenderer {
-    hostRenderer = null
-    coordinateAxes = null
-    camera = null
-    scene = null
-    renderer = null
-    ambientLight = null
-    height = 600 // size of render area
-    width = 600
-
-    constructor(width, height, renderer) {
-        this.width = width || this.width
-        this.height = height || this.height
-        this.init()
-        // this.setHostRenderer(renderer)
-    }
-
-    init() {
-        this.initRenderer()
-        this.initScene()
-        this.animate()
-    }
-
-    initRenderer() {
-        this.renderer = new THREE.WebGLRenderer({
-            antialias: true,
-            alpha: true
-        })
-        this.renderer.setSize(this.width, this.height)
-    }
-
-    initScene() {
-        this.scene = new THREE.Scene()
-        this.scene.layer = 6
-        // this.scene.background = new THREE.Color(0xebf2f7)
-
-        this.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0.1, 100)
-        // this.camera.position.set(1.5, 1.5, 1.5)
-        // this.camera.lookAt(0, 0, 0)
-        this.scene.add(this.camera)
-
-        this.ambientLight = new THREE.AmbientLight(0xcccccc, 1)
-        this.scene.add(this.ambientLight)
-
-        this.coordinateAxes = new CoordinateAxes()
-        this.scene.add(this.coordinateAxes)
-    }
-
-    render() {
-        if (this.renderer && this.scene && this.camera) {
-            this.update()
-            this.renderer.render(this.scene, this.camera)
-        }
-    }
-
-    animate() {
-        requestAnimationFrame(this.animate.bind(this))
-        this.render()
-    }
-
-    setHostRenderer(renderer) {
-        this.hostRenderer = renderer
-        this.update()
-    }
-
-    update() {
-        if (!this.hostRenderer || !this.hostRenderer.camera) {
-            return
-        }
-        const camera = this.hostRenderer.camera
-        if (camera) {
-            const target = new THREE.Vector3()
-            camera.getWorldDirection(target)
-            const up = camera.up
-            this.updateCameraDirection(target, up)
-        }
-    }
-
-    /**
-     * Update axes according to camera direction.
-     * Camera's direction is the only input factor for this class. It always look at the origin.
-     * @param direction
-     */
-    updateCameraDirection(direction, up) {
-        if (!this.camera || !direction) {
-            return
-        }
-        direction.normalize()
-        const distanceFactor = 200 // keep camera a little farer, so it looks better
-        const centerDelta = 0.3 // put the lookAt point to be in the first quadrant
-        this.camera.position.set(-direction.x * distanceFactor + centerDelta, -direction.y * distanceFactor + centerDelta, -direction.z * distanceFactor + centerDelta)
-        this.camera.lookAt(centerDelta, centerDelta, centerDelta) // it always looks at the origin
-        this.camera.up = up
-    }
-}

+ 1420 - 0
src/views/modelLibrary/components/online.vue

@@ -0,0 +1,1420 @@
+<template>
+    <div>
+        <div id="container"></div>
+    </div>
+</template>
+
+<script>
+import * as THREE from "three";
+import { TransformControls } from "three/examples/jsm/controls/TransformControls.js";
+import { DragControls } from "three/examples/jsm/controls/DragControls.js";
+import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
+import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader.js";
+import { MTLLoader } from "three/examples/jsm/loaders/MTLLoader.js";
+// import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js";
+// import { DDSLoader } from "three/examples/jsm/loaders/DDSLoader.js";
+import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
+import { ConvexGeometry } from "three/examples/jsm/geometries/ConvexGeometry.js";
+import {
+    showFullScreenLoading,
+    tryHideFullScreenLoading,
+} from "../../../axios/filter";
+import { mapState } from "vuex";
+
+export default {
+    name: "threeVehicleConfiguration", // 车辆配置详情中的threeJS
+    components: {},
+
+    data() {
+        return {
+            publicPath: process.env.BASE_URL,
+            scene: null,
+            camera: null,
+            renderer: null,
+            light: null,
+            transformControls: null,
+            geometryName: null,
+            controls: null,
+            mesh: null,
+            cube: null,
+            cacheList: [],
+            xAngle: 0,
+            yAngle: 0,
+            zAngle: 0,
+            container: null,
+            car: null,
+            cubeTexture: null,
+            raf: null,
+            canDrag: true, // 是否可移动
+            dragControls: null,
+            sensor: null, // 当前操作的传感器配置
+            ogt: null,
+            // scale: 2, // 物体加载换算倍数
+            // rate: 20, // 坐标换算倍数
+        };
+    },
+
+    computed: {
+        ...mapState(["scale"]),
+        // 坐标换算倍数
+        rate() {
+            return 40 / this.scale;
+        },
+    },
+
+    props: {
+        xValue: {
+            type: Number,
+            default: 0,
+        },
+        yValue: {
+            type: Number,
+            default: 0,
+        },
+        zValue: {
+            type: Number,
+            default: 0,
+        },
+        hValue: {
+            type: Number,
+            default: 0,
+        },
+        pValue: {
+            type: Number,
+            default: 0,
+        },
+        rValue: {
+            type: Number,
+            default: 0,
+        },
+        carModel: {
+            type: String,
+            default: "",
+        },
+        isAdd: {
+            type: Boolean,
+            default: false,
+        },
+        configList: {
+            default: {},
+            type: Object,
+        },
+    },
+
+    watch: {
+        xValue(newVal, oldVal) {
+            if (newVal === oldVal) return;
+
+            const obj = this.scene.getObjectByName("cube");
+            if (obj) obj.position.x = newVal || 0;
+
+            if (this.sensor) this.sensor.position.x = newVal || 0;
+        },
+        yValue(newVal, oldVal) {
+            if (newVal === oldVal) return;
+
+            const obj = this.scene.getObjectByName("cube");
+            if (obj) obj.position.y = newVal || 0;
+
+            if (this.sensor) this.sensor.position.y = newVal || 0;
+        },
+        zValue(newVal, oldVal) {
+            if (newVal === oldVal) return;
+
+            const obj = this.scene.getObjectByName("cube");
+            if (obj) obj.position.z = newVal || 0;
+
+            if (this.sensor) this.sensor.position.z = newVal || 0;
+        },
+        hValue(newVal, oldVal) {
+            if (newVal === oldVal) return;
+
+            let value = (newVal || 0) - 90;
+            value = (value * Math.PI) / 180;
+            this.xAngle = value;
+
+            const obj = this.scene.getObjectByName("cube");
+            if (obj) {
+                obj.rotation.set(this.xAngle, this.yAngle, this.zAngle);
+            }
+
+            // obj.rotateX(this.xAngle * -1);
+            // obj.rotateX(value);
+
+            // obj.rotation.x += value;
+            // var axis = new THREE.Vector3(0, 1, 0); //向量axis
+            // obj.rotateOnAxis(axis, value); //绕axis轴旋转π/8
+        },
+        pValue(newVal, oldVal) {
+            if (newVal === oldVal) return;
+
+            let value = newVal || 0;
+            value = (value * Math.PI) / 180;
+            this.yAngle = value;
+
+            const obj = this.scene.getObjectByName("cube");
+            if (obj) {
+                obj.rotation.set(this.xAngle, this.yAngle, this.zAngle);
+            }
+        },
+        rValue(newVal, oldVal) {
+            if (newVal === oldVal) return;
+
+            let value = newVal || 0;
+            value = (value * Math.PI) / 180;
+            this.zAngle = value;
+
+            const obj = this.scene.getObjectByName("cube");
+            if (obj) {
+                obj.rotation.set(this.xAngle, this.yAngle, this.zAngle);
+            }
+        },
+        carModel(newVal, oldVal) {
+            if (newVal && newVal != oldVal) {
+                this.initCar(newVal);
+            }
+        },
+    },
+
+    methods: {
+        // 场景
+        initScene() {
+            this.scene = new THREE.Scene();
+            let axes = new THREE.AxesHelper(1500);
+            this.scene.add(axes);
+            const gridHelper = new THREE.GridHelper(1000, 100);
+            gridHelper.material.opacity = 0.25;
+            gridHelper.material.transparent = true;
+            this.scene.add(gridHelper);
+
+            // const geometry = new THREE.BoxGeometry(100, 100, 100);
+            // const material = new THREE.MeshBasicMaterial({
+            //     color: 0xffffff,
+            //     opacity: 0.3,
+            //     transparent: true,
+            // });
+            // geometry.translate(100, 100, 100);
+            // const cube = new THREE.Mesh(geometry, material);
+            // this.scene.add(cube);
+
+            // let geometry = new THREE.BoxGeometry(10, 10, 10, 2, 2, 2);
+            // let material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
+            // let object = new THREE.Mesh(geometry, material);
+            // let edges = new THREE.VertexNormalsHelper(object, 2, 0x00ff00, 1);
+            // this.scene.add(object);
+            // this.scene.add(edges);
+
+            const genCubeUrls = function (prefix, postfix) {
+                return [
+                    prefix + "px" + postfix,
+                    prefix + "nx" + postfix,
+                    prefix + "py" + postfix,
+                    prefix + "ny" + postfix,
+                    prefix + "pz" + postfix,
+                    prefix + "nz" + postfix,
+                ];
+            };
+
+            const urls = genCubeUrls(`${this.publicPath}Park3Med/`, ".jpg");
+            // const urls = genCubeUrls(`${this.publicPath}6/`, ".png");
+
+            const cubeTextureLoader = new THREE.CubeTextureLoader();
+            const environmentMapTexture = cubeTextureLoader.load(urls);
+
+            // this.scene.background = environmentMapTexture;
+        },
+        // 相机
+        initCamera() {
+            /* this.camera = new THREE.OrthographicCamera(
+                this.container.clientWidth / -2,
+                this.container.clientWidth / 2,
+                this.container.clientHeight / 2,
+                this.container.clientHeight / -2,
+                1,
+                // 0.1,
+                1000
+            ); */
+
+            this.camera = new THREE.PerspectiveCamera(
+                75,
+                this.container.clientWidth / this.container.clientHeight,
+                0.1,
+                1000
+            );
+            // this.camera.layers.set(1);
+
+            // this.camera = new THREE.PerspectiveCamera(45, 1.5, 1, 1000);
+            // this.camera.position.set(600, 600, 600);
+            this.camera.position.set(200, 200, 200);
+            // this.camera.lookAt(this.scene.position);
+            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 light1 = new THREE.PointLight(0xffffff, 2, 100);
+            // light1.position.set(0, 0, -100);
+            // this.scene.add(light1);
+
+            // 平行光是沿着特定方向发射的光
+            const dirLight = new THREE.DirectionalLight(0xffffff, 0.5);
+            // const dirLight = new THREE.DirectionalLight(0xffffff);
+            // dirLight.position.set(0, 200, 100);
+            // dirLight.castShadow = true;
+            // dirLight.shadow.camera.top = 180;
+            // dirLight.shadow.camera.bottom = -100;
+            // dirLight.shadow.camera.left = -120;
+            // dirLight.shadow.camera.right = 120;
+
+            // dirLight.shadow.camera.near = 0.01;
+            // dirLight.shadow.camera.far = 60;
+            // dirLight.shadow.camera.top = 22;
+            // dirLight.shadow.camera.bottom = -22;
+            // dirLight.shadow.camera.left = -35;
+            // dirLight.shadow.camera.right = 35;
+            // // //设置阴影分辨率
+            // dirLight.shadow.mapSize.width = 2048; // default
+            // dirLight.shadow.mapSize.height = 2048; // default
+            // //阴影限制
+            // dirLight.shadow.radius = 1;
+            // this.scene.add(dirLight);
+
+            // const spotLight = new THREE.SpotLight(0xffffff);
+            // spotLight.position.set(100, 1000, 100);
+
+            // spotLight.castShadow = true;
+
+            // spotLight.shadow.mapSize.width = 1024;
+            // spotLight.shadow.mapSize.height = 1024;
+
+            // spotLight.shadow.camera.near = 500;
+            // spotLight.shadow.camera.far = 4000;
+            // spotLight.shadow.camera.fov = 30;
+
+            // this.scene.add(spotLight);
+        },
+        initTransform() {
+            // 添加平移控件
+            this.transformControls = new TransformControls(
+                this.camera,
+                this.renderer.domElement
+            );
+            this.transformControls.setMode("translate");
+            // 可能的值有"world" 和 "local"
+            this.transformControls.setSpace("world");
+            this.transformControls.addEventListener("objectChange", (e) => {
+                // console.log(e.target.object);
+                // this.$emit(
+                //     "posChange",
+                //     ((e.target.object.rotation.x * 360) / Math.PI) >> 0,
+                //     "h"
+                // );
+                if (!this.canDrag) return;
+                this.$emit(
+                    "posChange",
+                    (e.target.object.position.x + 0.5) >> 0,
+                    "x"
+                );
+                this.$emit(
+                    "posChange",
+                    (e.target.object.position.y + 0.5) >> 0,
+                    "y"
+                );
+                this.$emit(
+                    "posChange",
+                    (e.target.object.position.z + 0.5) >> 0,
+                    "z"
+                );
+            });
+            this.transformControls.addEventListener("mouseDown", (e) => {
+                this.controls.enabled = false;
+            });
+            this.transformControls.addEventListener("mouseUp", (e) => {
+                this.controls.enabled = true;
+            });
+            this.scene.add(this.transformControls);
+        },
+        // 初始化模型
+        initContent(r, position, rotation, type) {
+            var cubeGeometry = new THREE.ConeGeometry(
+                r || 45 * this.scale,
+                150 * this.scale,
+                4,
+                1,
+                false
+            );
+            cubeGeometry.translate(0, -75 * this.scale, 0);
+
+            let obj = {
+                color: 0x4c4c4c,
+                // wireframe: true,
+                transparent: true,
+                opacity: 0.3,
+                // ambient: 0x00ff00,
+                // emissive: 0xfaff72,
+                lightMapIntensity: 0.1,
+                // emissiveIntensity: 0.1,
+                // envMap: this.cubeTexture,
+                // side: THREE.DoubleSide,
+                // side: 2,
+            };
+
+            if (type === "camera") {
+                obj.emissive = 0x0000ff;
+                // obj.emissive = 0x000080;
+            } else if (type === "ogt") {
+                // obj.emissive = 0x228B22;
+                // obj.emissive = 0x006400;
+                obj.emissive = 0x008000;
+            } else if (type === "lidar") {
+                // obj.emissive = 0xff0000;
+                // obj.emissive = 0xE6A23C;
+                obj.emissive = 0xff4500;
+            } else if (type === "gps") {
+                // obj.emissive = 0xfaff72;
+                // obj.emissive = 0x9400D3;
+                obj.emissive = 0x8a2be2;
+            }
+
+            // var cubeMaterial = new THREE.MeshBasicMaterial(obj);
+            var cubeMaterial = new THREE.MeshLambertMaterial(obj);
+            this.cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
+            this.cube.name = this.geometryName || "cube";
+
+            if (position) {
+                this.cube.position.x = position.x;
+                this.cube.position.y = position.y;
+                this.cube.position.z = position.z;
+            }
+
+            if (rotation) {
+                this.cube.rotateX(rotation.x);
+                this.cube.rotateY(rotation.y);
+                this.cube.rotateZ(rotation.z);
+            }
+
+            this.scene.add(this.cube);
+
+            if (this.transformControls) {
+                this.transformControls.attach(this.cube);
+            }
+        },
+        // 添加拖拽控件
+        initDragControls() {
+            // 过滤不是 Mesh 的物体,例如辅助网格
+            var objects = [];
+            for (let i = 0; i < this.scene.children.length; i++) {
+                if (this.scene.children[i].isMesh) {
+                    objects.push(this.scene.children[i]);
+                }
+            }
+
+            if (this.dragControls) {
+                this.dragControls.deactivate();
+                this.dragControls.dispose();
+                this.dragControls = null;
+            }
+
+            // 初始化拖拽控件
+            this.dragControls = new DragControls(
+                objects,
+                this.camera,
+                this.renderer.domElement
+            );
+
+            // 鼠标略过事件
+            // this.dragControls.addEventListener("hoveron", (event) => {
+            //     // 让变换控件对象和选中的对象绑定
+            //     this.transformControls.attach(event.object);
+            // });
+
+            this.dragControls.addEventListener("drag", (e) => {
+                if (!this.canDrag) return;
+                // this.$emit("posChange", (e.object.position.x + 0.5) >> 0, "x");
+                // this.$emit("posChange", (e.object.position.y + 0.5) >> 0, "y");
+                // this.$emit("posChange", (e.object.position.z + 0.5) >> 0, "z");
+            });
+            this.dragControls.addEventListener("dragstart", (e) => {
+                this.controls.enabled = false;
+            });
+            this.dragControls.addEventListener("dragend", (e) => {
+                this.controls.enabled = true;
+            });
+        },
+        initCar0(model) {
+            if (this.car) {
+                // console.log(this.car);
+                this.scene.remove(this.car);
+                this.removeObj(this.car);
+                this.car = null;
+            }
+
+            // const loading = this.$loading({
+            //     lock: true,
+            //     text: "模型加载中,请稍等...",
+            //     // spinner: "el-icon-loading",
+            //     background: "rgba(0, 0, 0, 0.2)",
+            // });
+
+            showFullScreenLoading();
+
+            var that = this;
+            var loader = new GLTFLoader(); //创建一个FBX加载器
+
+            // loader.load(
+            //     `${this.publicPath}glb/AudiA6_10.glb`,
+            //     function (obj) {
+            loader.load(
+                model,
+                function (obj) {
+                    // loading.close();
+                    tryHideFullScreenLoading();
+                    // console.log(obj);
+
+                    /*  for (let i = 0; i < obj.children.length; i++) {
+                    // obj.children[i].position.set(0, -135, 0);
+                    // obj.children[i].position.set(18, 36, 0);
+                    // obj.children[i].scale.set(30, 30, 30);
+                    // obj.children[i].scale.set(0.45, 0.45, 0.45);
+                    obj.children[i].rotation.set(
+                        (-90 * Math.PI) / 180,
+                        0,
+                        (-180 * Math.PI) / 180
+                    );
+                    // obj.children[i].transparent.set(0.5);
+                    // that.transformControls.attach(obj.children[i]);
+                } */
+
+                    obj.scene.rotation.set(
+                        (-90 * Math.PI) / 180,
+                        0,
+                        (-180 * Math.PI) / 180
+                    );
+
+                    let scale = 30 * that.scale;
+                    obj.scene.scale.set(scale, scale, scale);
+                    // obj.scene.scale.set(30, 30, 30);
+
+                    // 查看动画数据  2个剪辑对象AnimationClip,一个有关键帧动画,一个没有
+                    // console.log(obj.animations);
+                    // that.scene.add(obj);
+                    that.scene.add(obj.scene);
+                    that.car = obj.scene;
+                },
+                (xhr) => {
+                    // console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
+                },
+                (error) => {
+                    // loading.close();
+                    tryHideFullScreenLoading();
+                    console.error(error);
+                }
+            );
+        },
+        initCar1() {
+            // const loader2 = new DDSLoader();
+            // const map1 = loader2.load(
+            //     `${this.publicPath}q5/AudiQ5_Texture.dds`
+            // );
+            // const map2 = loader2.load(`${this.publicPath}q5/env3.dds`);
+            // const map3 = loader2.load(
+            //     `${this.publicPath}q5/Tx_Blur_AudiQ5.dds`
+            // );
+            // const map4 = loader2.load(`${this.publicPath}q5/Tx_Driver.dds`);
+            // const map6 = loader2.load(
+            //     `${this.publicPath}q5/Tx_ln_AudiQ5_09.dds`
+            // );
+            // var that = this;
+            // var loader = new FBXLoader(); //创建一个FBX加载器
+            // // var loader = new GLTFLoader(); //创建一个FBX加载器
+            // // loader.load(`${this.publicPath}6/a8/audia8.fbx`, function (obj) {
+            // // loader.load(`${this.publicPath}6/q5/audiq5.fbx`, function (obj) {
+            // // loader.load(`${this.publicPath}6/a8/audia8.fbx`, function (obj) {
+            // // loader.load(`${this.publicPath}a8/audia8.fbx`, function (obj) {
+            // // loader.load(`${this.publicPath}q5/audiq5.fbx`, function (obj) {
+            // // loader.load(`${this.publicPath}lb/audiq5.fbx`, function (obj) {
+            // loader.load(
+            //     `${this.publicPath}lb/1/fbx/untitled.fbx`,
+            //     function (obj) {
+            //         // loader.load(`${this.publicPath}q6/audiq5.fbx`, function (obj) {
+            //         // loader.load(`${this.publicPath}untitled.fbx`, function (obj) {
+            //         // loader.load(`${this.publicPath}untitled.glb`, function (obj) {
+            //         // loader.load(`${this.publicPath}fbx/Samba Dancing.fbx`, function (obj) {
+            //         // 可以在控制台打印obj对象,找到animations属性
+            //         console.log(obj);
+            //         obj.name = "car";
+            //         // obj.map = map1;
+            //         function _ChangeMaterialEmissive(parent) {
+            //             parent.traverse(function (child) {
+            //                 // if (child instanceof THREE.Mesh) {
+            //                 if (child.isMesh) {
+            //                     // child.material.emissive = new THREE.Color(1, 1, 1);
+            //                     // child.material.emissive = child.material.color;
+            //                     // child.material.emissiveIntensity = 1;
+            //                     // child.material.emissiveMap = child.material.map;
+            //                     // child.material.envMap = child.material.map;
+            //                     // child.material.alphaMap = child.material.map;
+            //                     // child.material.aoMap = child.material.map;
+            //                     // child.material.bumpMap = child.material.map;
+            //                     // child.material.lightMap = child.material.map;
+            //                     // child.material.normalMap = child.material.map;
+            //                     // child.material.specularMap = child.material.map;
+            //                     // child.material.transparent = true;
+            //                     child.castShadow = true;
+            //                     child.receiveShadow = true;
+            //                 }
+            //             });
+            //         }
+            //         _ChangeMaterialEmissive(obj);
+            //         // obj.traverse(function (child) {
+            //         //     if (child.isMesh) {
+            //         //         // child.material.emissive = new THREE.Color(1, 1, 1);
+            //         //         child.material.emissive = child.material.color;
+            //         //         child.material.emissiveIntensity = 1;
+            //         //         child.material.emissiveMap = child.material.map;
+            //         //         child.castShadow = true;
+            //         //         child.receiveShadow = true;
+            //         //     }
+            //         // });
+            //         /*  for (let i = 0; i < obj.children.length; i++) {
+            //         // obj.children[i].position.set(0, -135, 0);
+            //         // obj.children[i].position.set(18, 36, 0);
+            //         // obj.children[i].scale.set(30, 30, 30);
+            //         // obj.children[i].scale.set(0.45, 0.45, 0.45);
+            //         obj.children[i].rotation.set(
+            //             (-90 * Math.PI) / 180,
+            //             0,
+            //             (-180 * Math.PI) / 180
+            //         );
+            //         // obj.children[i].transparent.set(0.5);
+            //         // that.transformControls.attach(obj.children[i]);
+            //     } */
+            //         obj.rotation.set(
+            //             (-90 * Math.PI) / 180,
+            //             0,
+            //             (-180 * Math.PI) / 180
+            //         );
+            //         // obj.scale.set(30, 30, 30);
+            //         // 查看动画数据  2个剪辑对象AnimationClip,一个有关键帧动画,一个没有
+            //         // console.log(obj.animations);
+            //         that.scene.add(obj);
+            //         // that.scene.add(obj.scene);
+            //     }
+            // );
+        },
+        initCar2() {
+            var that = this;
+            var loader2 = new THREE.ObjectLoader();
+            // var loader2 = new THREE.MeshLambertMaterial();
+            // loader2.load(`${that.publicPath}4.js`, function (obj) {
+            loader2.load(`${that.publicPath}car.json`, function (obj) {
+                // loader2.load(`${that.publicPath}Lidar.json`, function (obj) {
+                // console.log(obj);
+                obj.name = "car";
+                // console.log(obj.type);
+                // obj.position.set(0, 0, 0);
+                obj.scale.set(30, 30, 30);
+                obj.rotation.set(
+                    (-90 * Math.PI) / 180,
+                    0,
+                    (-90 * Math.PI) / 180
+                );
+                // obj.layers.set(1);
+                // that.transformControls.attach(obj);
+                that.scene.add(obj);
+            });
+        },
+        initCar3() {
+            var Loader = new MTLLoader(); //材质文件加载器
+            var loader = new OBJLoader(); //obj加载器
+            var that = this;
+
+            Loader.load(
+                // "../../../assets/common/image/female02/female02.mtl",
+                // "../../../../public/female02/female02.mtl",
+                // `${that.publicPath}male02/male02.mtl`,
+                // `${that.publicPath}GTR.mtl`,
+                // `${that.publicPath}lidar.mtl`,
+                // `${that.publicPath}female02/female02.mtl`,
+                // `${that.publicPath}new/audiq5.mtl`,
+                // `${that.publicPath}lb/obj/audiq5.mtl`,
+                // `${that.publicPath}lb/00obj/00.mtl`,
+                `${that.publicPath}lb/1/obj/untitled.mtl`,
+                function (materials) {
+                    // 返回一个包含材质的对象MaterialCreator
+                    // console.log(materials);
+                    // materials.transparent = true;
+                    // materials.opacity = 0.15;
+                    // materials.side = THREE.DoubleSide;
+                    // materials.depthWrite = false;
+                    //obj的模型会和MaterialCreator包含的材质对应起来
+                    loader.setMaterials(materials);
+                    loader.load(
+                        // "../../../../public/female02/female02.obj",
+                        // `${that.publicPath}female02/female02.obj`,
+                        // `${that.publicPath}new/audiq5.obj`,
+                        // `${that.publicPath}lb/00obj/00.obj`,
+                        `${that.publicPath}lb/1/obj/untitled.obj`,
+                        // `${that.publicPath}male02/male02.obj`,
+                        // `${that.publicPath}GTR.obj`,
+                        // `${that.publicPath}lidar.obj`,
+                        // `${that.publicPath}oddysey_2021.obj`,
+                        function (obj) {
+                            // console.log(obj);
+                            obj.name = "car";
+                            // console.log(obj.toJSON());
+                            // console.log(JSON.stringify(obj.toJSON()));
+                            // if (that.car) {
+                            //     that.scene.remove(that.car);
+                            // }
+
+                            for (let i = 0; i < obj.children.length; i++) {
+                                // obj.children[i].position.set(0, -135, 0);
+                                // obj.children[i].position.set(0, -30, 0);
+                                obj.children[i].position.set(0, 0, 0);
+                                // obj.children[i].scale.set(30, 30, 30);
+                                obj.children[i].rotation.set(
+                                    (-90 * Math.PI) / 180,
+                                    0,
+                                    (-180 * Math.PI) / 180
+                                );
+                                // obj.children[i].transparent.set(0.5);
+                                // that.transformControls.attach(obj.children[i]);
+                            }
+                            // that.transformControls.attach(that.cube);
+                            // console.log(obj.children[0].transparent);
+
+                            // that.transformControls.attach(obj);
+                            // that.car = obj;
+                            that.scene.add(obj); //返回的组对象插入场景中
+                            // this.camera.lookAt(obj);
+
+                            // loading.close();
+                            // that.camera.lookAt(obj.position);
+                            // 加载后操作
+                            // obj.children[0].scale.set(200, 200, 200); //缩放球体网格模型
+                            // 通过调节参数,地球表面的凹凸感更强
+                            // obj.children[0].material.normalScale.set(3, 3);
+                            // obj.children[0].position.set(100, 0, 0);
+                        }
+                    );
+                }
+            );
+        },
+        // 初始化车模型
+        initCar(model) {
+            // const loading = this.$loading({
+            //     lock: true,
+            //     text: "模型加载中,请稍等...",
+            //     // spinner: "el-icon-loading",
+            //     background: "rgba(0, 0, 0, 0.2)",
+            // });
+
+            // const car = this.scene.getObjectByName("car");
+            // console.log(car);
+            // console.log(this.scene);
+            // if (car) {
+            //     this.scene.remove(car);
+            // }
+
+            // console.log(type);
+
+            // if (type === "2") {
+            //     this.initCar1();
+            // } else if (type === "f") {
+            //     this.initCar2();
+            // } else if (type === "7") {
+            //     this.initCar3();
+            // } else {
+            //     this.initCar1();
+            // }
+
+            // console.log(model);
+            if (!model) return;
+            if (!model.includes(".glb")) return;
+
+            this.initCar0(model);
+
+            // console.log(this.scene);
+
+            // var Loader = new MTLLoader(); //材质文件加载器
+            // var loader = new OBJLoader(); //obj加载器
+            // var that = this;
+
+            /* var loader1 = new THREE.BufferGeometryLoader();
+            loader1.load(`${that.publicPath}car.json`, function (geometry) {
+            // loader1.load(`${that.publicPath}Lidar.json`, function (geometry) {
+                // 控制台查看加载放回的threejs对象结构
+                console.log(geometry);
+                var material = new THREE.MeshLambertMaterial({
+                    color: 0x0000ff,
+                }); //材质对象Material
+                var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
+                that.scene.add(mesh); //网格模型添加到场景中
+            }); */
+
+            // 没有材质文件,系统自动设置Phong网格材质
+            // loader.load("../../../assets/common/image/oddysey_2021.obj", function (obj) {
+            // loader.load("../../../assets/common/image/tree.obj", function (obj) {
+            // loader.load(`${that.publicPath}oddysey_2021.obj`, function (obj) {
+            // loader.load(`${that.publicPath}GTR.obj`, function (obj) {
+            /* loader.load(`${that.publicPath}Lidar.obj`, function (obj) {
+                if (that.car) {
+                    that.scene.remove(that.car);
+                }
+                console.log(666);
+                // console.log(JSON.stringify(obj.toJSON()));
+                that.car = obj;
+                // 控制台查看返回结构:包含一个网格模型Mesh的组Group
+                console.log(obj);
+                // loading.close();
+                // 查看加载器生成的材质对象:MeshPhongMaterial
+                // console.log(obj.children[0].material);
+                that.scene.add(obj);
+                for (let i = 0; i < obj.children.length; i++) {
+                    obj.children[i].position.set(0, 100, 0);
+                    obj.children[i].scale.set(20, 20, 20);
+                    // obj.children[i].layers.set(1);
+                }
+            }); */
+        },
+        // 初始化
+        init() {
+            this.initScene();
+            this.initCamera();
+            this.initRenderer();
+            this.initTransform();
+            this.initLight();
+            // this.initDragControls();
+
+            this.controls = new OrbitControls(
+                this.camera,
+                this.renderer.domElement
+            ); //创建控件对象
+            this.controls.update();
+            // this.controls.target = this.cube.position
+        },
+        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("container");
+            this.init();
+            this.animate();
+
+            window.addEventListener("resize", this.onWindowResize);
+        },
+        // 每编辑一个传感器则重新生成对应的物体
+        reset(type) {
+            this.canDrag = true;
+
+            if (this.cacheList.length > 0) {
+                this.scene.remove(...this.cacheList);
+                this.cacheList.forEach((i) => {
+                    this.clearCache(i);
+                });
+                this.cacheList = [];
+            }
+
+            this.sensor = null;
+
+            const obj1 = this.scene.getObjectByName("cube");
+            if (obj1) {
+                this.scene.remove(obj1);
+            }
+
+            this.xAngle = 0;
+            this.yAngle = 0;
+            this.zAngle = 0;
+
+            let z = +this.$parent.formA.sensorX || 0;
+            let x = +this.$parent.formA.sensorY || 0;
+            let y = +this.$parent.formA.sensorZ || 0;
+            let h = +this.$parent.formA.sensorP || 0;
+            let p = +this.$parent.formA.sensorR || 0;
+            let r = +this.$parent.formA.sensorH || 0;
+
+            x = Math.floor(x / this.rate);
+            y = Math.floor(y / this.rate);
+            z = Math.floor(z / this.rate);
+
+            this.initContent(
+                null,
+                { x, y, z },
+                {
+                    x: (-90 * Math.PI) / 180,
+                    y: 0,
+                    z: 0,
+                },
+                type
+            );
+
+            setTimeout(() => {
+                this.initSensor({ x, y, z }, type, true);
+
+                const obj = this.scene.getObjectByName("cube");
+
+                obj.position.x = x;
+                obj.position.y = y;
+                obj.position.z = z;
+
+                // obj.rotateX(0 * -1);
+                // obj.rotateX((h * Math.PI) / 180);
+                this.xAngle = ((h - 90) * Math.PI) / 180;
+
+                // obj.rotateY(0 * -1);
+                // obj.rotateY((p * Math.PI) / 180);
+                this.yAngle = (p * Math.PI) / 180;
+
+                // obj.rotateZ(0 * -1);
+                // obj.rotateZ((r * Math.PI) / 180);
+                this.zAngle = (r * Math.PI) / 180;
+                obj.rotation.set(this.xAngle, this.yAngle, this.zAngle);
+            }, 0);
+        },
+        // 初始化传感器
+        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 === "ogt1") {
+                var loader2 = new THREE.ObjectLoader();
+                loader2.load(
+                    `${that.publicPath}sensor/ogt/ogt.json`,
+                    function (obj) {
+                        // console.log(obj);
+                        that.cacheList.push(obj);
+                        for (let i = 0; i < obj.children.length; i++) {
+                            obj.children[i].scale.set(0.2, 0.2, 0.2);
+                        }
+                        obj.position.set(pos.x, pos.y, pos.z);
+                        obj.name = "ogt";
+                        if (canMove) {
+                            that.sensor = obj;
+                        }
+                        that.scene.add(obj);
+                    }
+                );
+                return;
+            }
+
+            if (type === "ogt1" && this.ogt) {
+                setTimeout(() => {
+                    let obj1 = this.ogt;
+                    // for (let i = 0; i < obj1.children.length; i++) {
+                    //     obj1.children[i].scale.set(0.2, 0.2, 0.2);
+                    // }
+                    obj1.position.set(pos.x, pos.y, pos.z);
+
+                    if (canMove) {
+                        that.sensor = obj1;
+                    }
+                    obj1.name = "ogt";
+                    // console.log(that.scene);
+
+                    that.scene.add(obj1); //返回的组对象插入场景中
+                }, 600);
+                return;
+            }
+
+            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`;
+            }
+
+            let loading = null;
+            if (type === "ogt") {
+                // loading = this.$loading({
+                //     lock: true,
+                //     text: "模型加载中,请稍等...",
+                //     // spinner: "el-icon-loading",
+                //     background: "rgba(0, 0, 0, 0.2)",
+                // });
+                showFullScreenLoading();
+            }
+
+            Loader.load(
+                mtlUrl,
+                function (materials) {
+                    // console.log(materials);
+                    loader.setMaterials(materials);
+                    loader.load(objUrl, function (obj) {
+                        // console.log(obj);
+                        // console.log(obj.clone());
+                        // console.log(JSON.stringify(obj.toJSON()));
+                        // if (type === "ogt" && !that.ogt) {
+                        //     that.ogt = obj.clone();
+                        // }
+
+                        if (type === "ogt") {
+                            // loading.close();
+                            tryHideFullScreenLoading();
+                        }
+
+                        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(0.8, 0.8, 0.8);
+                            } else if (type === "ogt") {
+                                obj.children[i].scale.set(0.2, 0.2, 0.2);
+                            } else if (type === "lidar") {
+                                obj.children[i].scale.set(0.1, 0.1, 0.1);
+                            } else if (type === "gps") {
+                                obj.children[i].scale.set(40, 40, 40);
+                            }
+                            // obj.children[i].position.set(0, 0, 0);
+                            // obj.children[i].geometry.translate(pos.x, pos.y, pos.z);
+                            // obj.children[i].position.set(pos.x, pos.y, pos.z);
+                            // obj.children[i].geometry.translate(-pos.x, -pos.y, -pos.z);
+                            // obj.children[i].scale.set(30, 30, 30);
+                        }
+                        obj.position.set(pos.x, pos.y, pos.z);
+                        // obj.geometry.translate.set(pos.x, pos.y, pos.z);
+
+                        if (canMove) {
+                            that.sensor = obj;
+                        }
+
+                        that.scene.add(obj); //返回的组对象插入场景中
+                    });
+                },
+                (xhr) => {
+                    // console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
+                },
+                (error) => {
+                    if (type === "ogt") {
+                        // loading.close();
+                        tryHideFullScreenLoading();
+                    }
+                    console.error(error);
+                }
+            );
+        },
+        // 初始化已保存过的传感器
+        initContentToShow(r, position, rotation, type) {
+            var cubeGeometry = new THREE.ConeGeometry(
+                r || 45 * this.scale,
+                150 * this.scale,
+                4,
+                1,
+                false
+            );
+            cubeGeometry.translate(0, -75 * this.scale, 0);
+
+            let obj = {
+                transparent: true,
+                opacity: 0.3,
+                // emissive: 0xfaff72,
+                lightMapIntensity: 0.1,
+                color: 0x4c4c4c,
+            };
+
+            if (type === "camera") {
+                obj.emissive = 0x000080;
+                // obj.color = 0xfaff72;
+            } else if (type === "ogt") {
+                obj.emissive = 0x008000;
+                // obj.color = 0x33cc66;
+            } else if (type === "lidar") {
+                // obj.emissive = 0xff0000;
+                // obj.color = 0xcc3366;
+                obj.emissive = 0xff4500;
+            } else if (type === "gps") {
+                // obj.emissive = 0xfaff72;
+                // obj.color = 0x3366cc;
+                obj.emissive = 0x8a2be2;
+            }
+
+            var cubeMaterial = new THREE.MeshLambertMaterial(obj);
+            // var cubeMaterial = new THREE.MeshBasicMaterial(obj);
+
+            var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
+            cube.name = this.geometryName || "cubeA";
+            cube.rotateX((-90 * Math.PI) / 180);
+
+            if (position) {
+                cube.position.x = position.x;
+                cube.position.y = position.y;
+                cube.position.z = position.z;
+            }
+            if (rotation) {
+                // cube.rotateX(0 * -1);
+                // cube.rotateX((rotation.x * Math.PI) / 180);
+                // cube.rotateY(0 * -1);
+                // cube.rotateY((rotation.y * Math.PI) / 180);
+                // cube.rotateZ(0 * -1);
+                // cube.rotateZ((rotation.z * Math.PI) / 180);
+
+                cube.rotation.set(
+                    ((rotation.x - 90) * Math.PI) / 180,
+                    (rotation.y * Math.PI) / 180,
+                    (rotation.z * Math.PI) / 180
+                );
+            }
+            this.cacheList.push(cube);
+            this.scene.add(cube);
+        },
+        // 生成一种类型的全部显示器
+        showSensor(sensor, type) {
+            if (sensor && Array.isArray(sensor) && sensor.length > 0) {
+                sensor.forEach((item) => {
+                    this.initContentToShow(
+                        null,
+                        {
+                            z: Math.floor(item.sensorX / this.rate || 0),
+                            x: Math.floor(item.sensorY / this.rate || 0),
+                            y: Math.floor(item.sensorZ / this.rate || 0),
+                        },
+                        {
+                            x: +item.sensorP,
+                            y: +item.sensorR,
+                            z: +item.sensorH,
+                        },
+                        type
+                    );
+
+                    this.initSensor(
+                        {
+                            z: Math.floor(item.sensorX / this.rate || 0),
+                            x: Math.floor(item.sensorY / this.rate || 0),
+                            y: Math.floor(item.sensorZ / this.rate || 0),
+                        },
+                        type,
+                        false
+                    );
+                });
+            }
+        },
+        // 显示全部
+        showAll() {
+            // 避免重复加载所有传感器
+            if (!this.canDrag) return;
+
+            this.canDrag = false;
+            if (this.cacheList.length > 0) {
+                this.scene.remove(...this.cacheList);
+                this.cacheList = [];
+            }
+
+            const obj = this.scene.getObjectByName("cube");
+            if (obj) {
+                this.scene.remove(obj);
+            }
+
+            if (this.dragControls) {
+                this.dragControls.deactivate();
+                this.dragControls.dispose();
+                this.dragControls = null;
+            }
+
+            if (this.transformControls) {
+                this.transformControls.detach();
+            }
+
+            // console.log(this.configList);
+
+            this.showSensor(this.configList.camera, "camera");
+            this.showSensor(this.configList.ogt, "ogt");
+            this.showSensor(this.configList.lidar, "lidar");
+            this.showSensor(this.configList.gps, "gps");
+        },
+        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;
+        },
+        showTX() {
+            var pointsArr1 = [
+                // [5, -1, 33],
+                // [5, 11, 33],
+                // [-5, -1, 33],
+                // [-5, 11, 33],
+                [0, 0, 0],
+                [10, -11, 66],
+                [30, 31, 66],
+                [-20, -21, 66],
+                [-30, 21, 66],
+            ];
+
+            let x = 0,
+                y = 0,
+                z = 0;
+
+            let r = 60;
+            z = r;
+
+            let a = 120,
+                b = 40;
+
+            x = Math.tan(THREE.MathUtils.degToRad(a / 2)) * r;
+            y = Math.tan(THREE.MathUtils.degToRad(b / 2)) * r;
+
+            let x1 = 0,
+                y1 = 0,
+                z1 = 0;
+
+            let r1 = 20;
+            z1 = r1;
+
+            x1 = Math.tan(THREE.MathUtils.degToRad(a / 2)) * r1;
+            y1 = Math.tan(THREE.MathUtils.degToRad(b / 2)) * r1;
+
+            let pointsArr2 = [
+                [0, 0, 0],
+                // [-x1, y1, z1],
+                // [-x1, -y1, z1],
+                // [x1, y1, z1],
+                // [x1, -y1, z1],
+                [-x, y, z],
+                [-x, -y, z],
+                [x, y, z],
+                [x, -y, z],
+            ];
+
+            let x2 = 0,
+                y2 = 0,
+                z2 = 0,
+                x3 = 0,
+                y3 = 0,
+                z3 = 0,
+                x4 = 0,
+                y4 = 0,
+                z4 = 0,
+                x6 = 0,
+                y6 = 0,
+                z6 = 0,
+                r2 = 90,
+                a2 = 30,
+                b2 = 60,
+                c2 = 90,
+                d2 = 60;
+
+            x2 = Math.tan(THREE.MathUtils.degToRad(a2 / 2)) * r2;
+            y2 = Math.tan(THREE.MathUtils.degToRad(b2 / 2)) * r2;
+            x3 = Math.tan(THREE.MathUtils.degToRad(c2 / 2)) * r2;
+            y3 = Math.tan(THREE.MathUtils.degToRad(d2 / 2)) * r2;
+
+            let pointsArr3 = [
+                [0, 0, 0],
+                [-x2, y3, r2],
+                [-x3, -y3, r2],
+                [x2, y2, r2],
+                [x3, -y2, r2],
+            ];
+            // console.log(pointsArr3);
+
+            let points = pointsArr3.map(
+                (d) => new THREE.Vector3(d[0], d[1], d[2])
+            );
+
+            let material = new THREE.MeshPhongMaterial({
+                color: 0x2c85e1,
+                shininess: 60,
+                specular: 0x2c85e1,
+                // opacity: 0.5,
+                // transparent: true,
+            });
+
+            let tixing = new ConvexGeometry(points);
+            //通过ConvexGeometry凸包绘制一个梯台,当然也可以使用ExtrudeGeometry挤压几何体,
+            let tixingMesh = new THREE.Mesh(tixing, material);
+            this.scene.add(tixingMesh);
+            // console.log(tixingMesh);
+
+            /* let vertices = [];
+
+            vertices.push(-155, 24, 90);
+            vertices.push(-63, -24, 90);
+            vertices.push(155, 91, 90);
+            vertices.push(63, -90, 90);
+
+            const geometry1 = new THREE.BufferGeometry();
+            geometry1.setAttribute(
+                "position",
+                new THREE.Float32BufferAttribute(vertices, 3)
+            );
+
+            const material1 = new THREE.PointsMaterial({
+                color: 0xff0000,
+                size: 10,
+                fog: false,
+            });
+
+            const points1 = new THREE.Points(geometry1, material1);
+
+            this.scene.add(points1); */
+
+            // if (this.transformControls) {
+            //     this.transformControls.attach(tixingMesh);
+            // }
+
+            // const a = new THREE.Vector3(1, 1, 0);
+            // const b = new THREE.Vector3(0, 0, 0);
+            // const d = a.distanceTo(b);
+            // const e = a.angleTo(b);
+
+            // console.log(d, e, (e * 180) / Math.PI, THREE.MathUtils.radToDeg(e));
+
+            // (value * Math.PI) / 180;
+        },
+    },
+
+    mounted() {
+        this.go();
+        // this.showTX();
+
+        // console.log(THREE.Loader.Handlers.add);
+        // THREE.Loader.Handlers.add( /\.dds$/i, new DDSLoader() );
+
+        // console.log(new THREE.LoadingManager()); RGBELoader
+        // let dds = new THREE.LoadingManager();
+        // dds.addHandler(/\.dds$/i, new DDSLoader());
+        // dds.addHandler(/\.rgb$/i, new RGBELoader());
+        // console.log(dds);
+
+        // THREE.DefaultLoadingManager.addHandler(/\.dds$/i, new DDSLoader());
+        // THREE.DefaultLoadingManager.addHandler(/\.rgb$/i, new RGBELoader());
+        // console.log(THREE.DefaultLoadingManager);
+
+        // console.log(THREE.LoadingManager.addHandler);
+        // THREE.Loader.Handlers.add( /\.dds$/i, new DDSLoader());
+        // THREE.Loader.addHandler(/\.dds$/i, new DDSLoader());
+        // THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
+        // THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
+
+        // if (!this.isAdd) {
+        //     setTimeout(() => {
+        //         this.initCar();
+        //     }, 270);
+        // }
+    },
+    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;
+
+        THREE.Cache.clear();
+    },
+};
+</script>
+
+<style lang="less" scoped>
+#container {
+    width: 100%;
+    height: calc(100vh - 125px);
+}
+</style>

+ 1812 - 0
src/views/modelLibrary/components/threeVehicleConC2.vue

@@ -0,0 +1,1812 @@
+<template>
+    <div>
+        <div id="container"></div>
+    </div>
+</template>
+
+<script>
+import * as THREE from "three";
+import { TransformControls } from "three/examples/jsm/controls/TransformControls.js";
+import { DragControls } from "three/examples/jsm/controls/DragControls.js";
+import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
+import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader.js";
+import { MTLLoader } from "three/examples/jsm/loaders/MTLLoader.js";
+// import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js";
+// import { DDSLoader } from "three/examples/jsm/loaders/DDSLoader.js";
+import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
+import { ConvexGeometry } from "three/examples/jsm/geometries/ConvexGeometry.js";
+import { LineGeometry } from "three/examples/jsm/lines/LineGeometry.js";
+import { LineSegmentsGeometry } from "three/examples/jsm/lines/LineSegmentsGeometry.js";
+import { LineMaterial } from "three/examples/jsm/lines/LineMaterial.js";
+import { LineSegments2 } from "three/examples/jsm/lines/LineSegments2.js";
+import { Line2 } from "three/examples/jsm/lines/Line2.js";
+import {
+    showFullScreenLoading,
+    tryHideFullScreenLoading,
+} from "../../../axios/filter";
+import { mapState } from "vuex";
+
+export default {
+    name: "threeVehicleConfiguration", // 车辆配置详情中的threeJS
+    components: {},
+
+    data() {
+        return {
+            publicPath: process.env.BASE_URL,
+            scene: null,
+            scene2: null,
+            camera: null,
+            camera2: null,
+            renderer: null,
+            light: null,
+            transformControls: null,
+            geometryName: null,
+            controls: null,
+            mesh: null,
+            cube: null,
+            cacheList: [],
+            xAngle: 0,
+            yAngle: 0,
+            zAngle: 0,
+            container: null,
+            car: null,
+            cubeTexture: null,
+            raf: null,
+            canDrag: true, // 是否可移动
+            dragControls: null,
+            sensor: null, // 当前操作的传感器配置
+            ogt: null,
+            // scale: 2, // 物体加载换算倍数
+            // rate: 20, // 坐标换算倍数
+        };
+    },
+
+    computed: {
+        ...mapState(["scale"]),
+        // 坐标换算倍数
+        rate() {
+            return 40 / this.scale;
+        },
+    },
+
+    props: {
+        xValue: {
+            type: Number,
+            default: 0,
+        },
+        yValue: {
+            type: Number,
+            default: 0,
+        },
+        zValue: {
+            type: Number,
+            default: 0,
+        },
+        hValue: {
+            type: Number,
+            default: 0,
+        },
+        pValue: {
+            type: Number,
+            default: 0,
+        },
+        rValue: {
+            type: Number,
+            default: 0,
+        },
+        carModel: {
+            type: String,
+            default: "",
+        },
+        isAdd: {
+            type: Boolean,
+            default: false,
+        },
+        configList: {
+            default: {},
+            type: Object,
+        },
+    },
+
+    watch: {
+        xValue(newVal, oldVal) {
+            if (newVal === oldVal) return;
+
+            const obj = this.scene.getObjectByName("cube");
+            if (obj) obj.position.x = newVal || 0;
+
+            if (this.sensor) this.sensor.position.x = newVal || 0;
+        },
+        yValue(newVal, oldVal) {
+            if (newVal === oldVal) return;
+
+            const obj = this.scene.getObjectByName("cube");
+            if (obj) obj.position.y = newVal || 0;
+
+            if (this.sensor) this.sensor.position.y = newVal || 0;
+        },
+        zValue(newVal, oldVal) {
+            if (newVal === oldVal) return;
+
+            const obj = this.scene.getObjectByName("cube");
+            if (obj) obj.position.z = newVal || 0;
+
+            if (this.sensor) this.sensor.position.z = newVal || 0;
+        },
+        hValue(newVal, oldVal) {
+            if (newVal === oldVal) return;
+
+            let value = (newVal || 0) - 90;
+            value = (value * Math.PI) / 180;
+            this.xAngle = value;
+
+            const obj = this.scene.getObjectByName("cube");
+            if (obj) {
+                obj.rotation.set(this.xAngle, this.yAngle, this.zAngle);
+            }
+
+            // obj.rotateX(this.xAngle * -1);
+            // obj.rotateX(value);
+
+            // obj.rotation.x += value;
+            // var axis = new THREE.Vector3(0, 1, 0); //向量axis
+            // obj.rotateOnAxis(axis, value); //绕axis轴旋转π/8
+        },
+        pValue(newVal, oldVal) {
+            if (newVal === oldVal) return;
+
+            let value = newVal || 0;
+            value = (value * Math.PI) / 180;
+            this.yAngle = value;
+
+            const obj = this.scene.getObjectByName("cube");
+            if (obj) {
+                obj.rotation.set(this.xAngle, this.yAngle, this.zAngle);
+            }
+        },
+        rValue(newVal, oldVal) {
+            if (newVal === oldVal) return;
+
+            let value = newVal || 0;
+            value = (value * Math.PI) / 180;
+            this.zAngle = value;
+
+            const obj = this.scene.getObjectByName("cube");
+            if (obj) {
+                obj.rotation.set(this.xAngle, this.yAngle, this.zAngle);
+            }
+        },
+        carModel(newVal, oldVal) {
+            if (newVal && newVal != oldVal) {
+                this.initCar(newVal);
+            }
+        },
+    },
+
+    methods: {
+        // 场景
+        initScene() {
+            this.scene = new THREE.Scene();
+            let axes = new THREE.AxesHelper(1500);
+            this.scene.add(axes);
+
+            const gridHelper = new THREE.GridHelper(1000, 100);
+            gridHelper.material.opacity = 0.25;
+            gridHelper.material.transparent = true;
+            this.scene.add(gridHelper);
+
+            // const geometry = new THREE.BoxGeometry(100, 100, 100);
+            // const material = new THREE.MeshBasicMaterial({
+            //     color: 0xffffff,
+            //     opacity: 0.3,
+            //     transparent: true,
+            // });
+            // geometry.translate(100, 100, 100);
+            // const cube = new THREE.Mesh(geometry, material);
+            // this.scene.add(cube);
+
+            // let geometry = new THREE.BoxGeometry(10, 10, 10, 2, 2, 2);
+            // let material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
+            // let object = new THREE.Mesh(geometry, material);
+            // let edges = new THREE.VertexNormalsHelper(object, 2, 0x00ff00, 1);
+            // this.scene.add(object);
+            // this.scene.add(edges);
+
+            const genCubeUrls = function (prefix, postfix) {
+                return [
+                    prefix + "px" + postfix,
+                    prefix + "nx" + postfix,
+                    prefix + "py" + postfix,
+                    prefix + "ny" + postfix,
+                    prefix + "pz" + postfix,
+                    prefix + "nz" + postfix,
+                ];
+            };
+
+            const urls = genCubeUrls(`${this.publicPath}Park3Med/`, ".jpg");
+            // const urls = genCubeUrls(`${this.publicPath}6/`, ".png");
+
+            const cubeTextureLoader = new THREE.CubeTextureLoader();
+            const environmentMapTexture = cubeTextureLoader.load(urls);
+
+            // this.scene.background = environmentMapTexture;
+        },
+        // 相机
+        initCamera() {
+            /* this.camera = new THREE.OrthographicCamera(
+                this.container.clientWidth / -2,
+                this.container.clientWidth / 2,
+                this.container.clientHeight / 2,
+                this.container.clientHeight / -2,
+                1,
+                // 0.1,
+                1000
+            ); */
+
+            this.camera = new THREE.PerspectiveCamera(
+                75,
+                this.container.clientWidth / this.container.clientHeight,
+                0.1,
+                1000
+            );
+
+            // this.camera2 = new THREE.PerspectiveCamera(75, 1, 0.1, 1000);
+            // this.camera2 = new THREE.PerspectiveCamera(40, 1, 1, 1000);
+            // this.camera2.position.copy(this.camera.position);
+            // this.camera.layers.set(1);
+
+            // this.camera = new THREE.PerspectiveCamera(45, 1.5, 1, 1000);
+            // this.camera.position.set(600, 600, 600);
+            // this.camera.position.set(200, 200, 200);
+            // this.camera.lookAt(this.scene.position);
+            // this.scene.add(this.camera);
+            // this.scene.add(this.camera2);
+        },
+        // 渲染器
+        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 light1 = new THREE.PointLight(0xffffff, 2, 100);
+            // light1.position.set(0, 0, -100);
+            // this.scene.add(light1);
+
+            // 平行光是沿着特定方向发射的光
+            const dirLight = new THREE.DirectionalLight(0xffffff, 0.5);
+            // const dirLight = new THREE.DirectionalLight(0xffffff);
+            // dirLight.position.set(0, 200, 100);
+            // dirLight.castShadow = true;
+            // dirLight.shadow.camera.top = 180;
+            // dirLight.shadow.camera.bottom = -100;
+            // dirLight.shadow.camera.left = -120;
+            // dirLight.shadow.camera.right = 120;
+
+            // dirLight.shadow.camera.near = 0.01;
+            // dirLight.shadow.camera.far = 60;
+            // dirLight.shadow.camera.top = 22;
+            // dirLight.shadow.camera.bottom = -22;
+            // dirLight.shadow.camera.left = -35;
+            // dirLight.shadow.camera.right = 35;
+            // // //设置阴影分辨率
+            // dirLight.shadow.mapSize.width = 2048; // default
+            // dirLight.shadow.mapSize.height = 2048; // default
+            // //阴影限制
+            // dirLight.shadow.radius = 1;
+            // this.scene.add(dirLight);
+
+            // const spotLight = new THREE.SpotLight(0xffffff);
+            // spotLight.position.set(100, 1000, 100);
+
+            // spotLight.castShadow = true;
+
+            // spotLight.shadow.mapSize.width = 1024;
+            // spotLight.shadow.mapSize.height = 1024;
+
+            // spotLight.shadow.camera.near = 500;
+            // spotLight.shadow.camera.far = 4000;
+            // spotLight.shadow.camera.fov = 30;
+
+            // this.scene.add(spotLight);
+        },
+        initTransform() {
+            // 添加平移控件
+            this.transformControls = new TransformControls(
+                this.camera,
+                this.renderer.domElement
+            );
+            this.transformControls.setMode("translate");
+            // 可能的值有"world" 和 "local"
+            this.transformControls.setSpace("world");
+            this.transformControls.addEventListener("objectChange", (e) => {
+                // console.log(e.target.object);
+                // this.$emit(
+                //     "posChange",
+                //     ((e.target.object.rotation.x * 360) / Math.PI) >> 0,
+                //     "h"
+                // );
+                if (!this.canDrag) return;
+                this.$emit(
+                    "posChange",
+                    (e.target.object.position.x + 0.5) >> 0,
+                    "x"
+                );
+                this.$emit(
+                    "posChange",
+                    (e.target.object.position.y + 0.5) >> 0,
+                    "y"
+                );
+                this.$emit(
+                    "posChange",
+                    (e.target.object.position.z + 0.5) >> 0,
+                    "z"
+                );
+            });
+            this.transformControls.addEventListener("mouseDown", (e) => {
+                this.controls.enabled = false;
+            });
+            this.transformControls.addEventListener("mouseUp", (e) => {
+                this.controls.enabled = true;
+            });
+            this.scene.add(this.transformControls);
+        },
+        // 初始化模型
+        initContent(r, position, rotation, type) {
+            var cubeGeometry = new THREE.ConeGeometry(
+                r || 45 * this.scale,
+                150 * this.scale,
+                4,
+                1,
+                false
+            );
+            cubeGeometry.translate(0, -75 * this.scale, 0);
+
+            let obj = {
+                color: 0x4c4c4c,
+                // wireframe: true,
+                transparent: true,
+                opacity: 0.3,
+                // ambient: 0x00ff00,
+                // emissive: 0xfaff72,
+                lightMapIntensity: 0.1,
+                // emissiveIntensity: 0.1,
+                // envMap: this.cubeTexture,
+                // side: THREE.DoubleSide,
+                // side: 2,
+            };
+
+            if (type === "camera") {
+                obj.emissive = 0x0000ff;
+                // obj.emissive = 0x000080;
+            } else if (type === "ogt") {
+                // obj.emissive = 0x228B22;
+                // obj.emissive = 0x006400;
+                obj.emissive = 0x008000;
+            } else if (type === "lidar") {
+                // obj.emissive = 0xff0000;
+                // obj.emissive = 0xE6A23C;
+                obj.emissive = 0xff4500;
+            } else if (type === "gps") {
+                // obj.emissive = 0xfaff72;
+                // obj.emissive = 0x9400D3;
+                obj.emissive = 0x8a2be2;
+            }
+
+            // var cubeMaterial = new THREE.MeshBasicMaterial(obj);
+            var cubeMaterial = new THREE.MeshLambertMaterial(obj);
+            this.cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
+            this.cube.name = this.geometryName || "cube";
+
+            if (position) {
+                this.cube.position.x = position.x;
+                this.cube.position.y = position.y;
+                this.cube.position.z = position.z;
+            }
+
+            if (rotation) {
+                this.cube.rotateX(rotation.x);
+                this.cube.rotateY(rotation.y);
+                this.cube.rotateZ(rotation.z);
+            }
+
+            this.scene.add(this.cube);
+
+            if (this.transformControls) {
+                this.transformControls.attach(this.cube);
+            }
+        },
+        // 添加拖拽控件
+        initDragControls() {
+            // 过滤不是 Mesh 的物体,例如辅助网格
+            var objects = [];
+            for (let i = 0; i < this.scene.children.length; i++) {
+                if (this.scene.children[i].isMesh) {
+                    objects.push(this.scene.children[i]);
+                }
+            }
+
+            if (this.dragControls) {
+                this.dragControls.deactivate();
+                this.dragControls.dispose();
+                this.dragControls = null;
+            }
+
+            // 初始化拖拽控件
+            this.dragControls = new DragControls(
+                objects,
+                this.camera,
+                this.renderer.domElement
+            );
+
+            // 鼠标略过事件
+            // this.dragControls.addEventListener("hoveron", (event) => {
+            //     // 让变换控件对象和选中的对象绑定
+            //     this.transformControls.attach(event.object);
+            // });
+
+            this.dragControls.addEventListener("drag", (e) => {
+                if (!this.canDrag) return;
+                // this.$emit("posChange", (e.object.position.x + 0.5) >> 0, "x");
+                // this.$emit("posChange", (e.object.position.y + 0.5) >> 0, "y");
+                // this.$emit("posChange", (e.object.position.z + 0.5) >> 0, "z");
+            });
+            this.dragControls.addEventListener("dragstart", (e) => {
+                this.controls.enabled = false;
+            });
+            this.dragControls.addEventListener("dragend", (e) => {
+                this.controls.enabled = true;
+            });
+        },
+        initCar0(model) {
+            if (this.car) {
+                // console.log(this.car);
+                this.scene.remove(this.car);
+                this.removeObj(this.car);
+                this.car = null;
+            }
+
+            // const loading = this.$loading({
+            //     lock: true,
+            //     text: "模型加载中,请稍等...",
+            //     // spinner: "el-icon-loading",
+            //     background: "rgba(0, 0, 0, 0.2)",
+            // });
+
+            showFullScreenLoading();
+
+            var that = this;
+            var loader = new GLTFLoader(); //创建一个FBX加载器
+
+            // loader.load(
+            //     `${this.publicPath}glb/AudiA6_10.glb`,
+            //     function (obj) {
+            loader.load(
+                model,
+                function (obj) {
+                    // loading.close();
+                    tryHideFullScreenLoading();
+                    // console.log(obj);
+
+                    /*  for (let i = 0; i < obj.children.length; i++) {
+                    // obj.children[i].position.set(0, -135, 0);
+                    // obj.children[i].position.set(18, 36, 0);
+                    // obj.children[i].scale.set(30, 30, 30);
+                    // obj.children[i].scale.set(0.45, 0.45, 0.45);
+                    obj.children[i].rotation.set(
+                        (-90 * Math.PI) / 180,
+                        0,
+                        (-180 * Math.PI) / 180
+                    );
+                    // obj.children[i].transparent.set(0.5);
+                    // that.transformControls.attach(obj.children[i]);
+                } */
+
+                    obj.scene.rotation.set(
+                        (-90 * Math.PI) / 180,
+                        0,
+                        (-180 * Math.PI) / 180
+                    );
+
+                    let scale = 30 * that.scale;
+                    obj.scene.scale.set(scale, scale, scale);
+                    // obj.scene.scale.set(30, 30, 30);
+
+                    // 查看动画数据  2个剪辑对象AnimationClip,一个有关键帧动画,一个没有
+                    // console.log(obj.animations);
+                    // that.scene.add(obj);
+                    that.scene.add(obj.scene);
+                    that.car = obj.scene;
+                },
+                (xhr) => {
+                    // console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
+                },
+                (error) => {
+                    // loading.close();
+                    tryHideFullScreenLoading();
+                    console.error(error);
+                }
+            );
+        },
+        initCar1() {
+            // const loader2 = new DDSLoader();
+            // const map1 = loader2.load(
+            //     `${this.publicPath}q5/AudiQ5_Texture.dds`
+            // );
+            // const map2 = loader2.load(`${this.publicPath}q5/env3.dds`);
+            // const map3 = loader2.load(
+            //     `${this.publicPath}q5/Tx_Blur_AudiQ5.dds`
+            // );
+            // const map4 = loader2.load(`${this.publicPath}q5/Tx_Driver.dds`);
+            // const map6 = loader2.load(
+            //     `${this.publicPath}q5/Tx_ln_AudiQ5_09.dds`
+            // );
+            // var that = this;
+            // var loader = new FBXLoader(); //创建一个FBX加载器
+            // // var loader = new GLTFLoader(); //创建一个FBX加载器
+            // // loader.load(`${this.publicPath}6/a8/audia8.fbx`, function (obj) {
+            // // loader.load(`${this.publicPath}6/q5/audiq5.fbx`, function (obj) {
+            // // loader.load(`${this.publicPath}6/a8/audia8.fbx`, function (obj) {
+            // // loader.load(`${this.publicPath}a8/audia8.fbx`, function (obj) {
+            // // loader.load(`${this.publicPath}q5/audiq5.fbx`, function (obj) {
+            // // loader.load(`${this.publicPath}lb/audiq5.fbx`, function (obj) {
+            // loader.load(
+            //     `${this.publicPath}lb/1/fbx/untitled.fbx`,
+            //     function (obj) {
+            //         // loader.load(`${this.publicPath}q6/audiq5.fbx`, function (obj) {
+            //         // loader.load(`${this.publicPath}untitled.fbx`, function (obj) {
+            //         // loader.load(`${this.publicPath}untitled.glb`, function (obj) {
+            //         // loader.load(`${this.publicPath}fbx/Samba Dancing.fbx`, function (obj) {
+            //         // 可以在控制台打印obj对象,找到animations属性
+            //         console.log(obj);
+            //         obj.name = "car";
+            //         // obj.map = map1;
+            //         function _ChangeMaterialEmissive(parent) {
+            //             parent.traverse(function (child) {
+            //                 // if (child instanceof THREE.Mesh) {
+            //                 if (child.isMesh) {
+            //                     // child.material.emissive = new THREE.Color(1, 1, 1);
+            //                     // child.material.emissive = child.material.color;
+            //                     // child.material.emissiveIntensity = 1;
+            //                     // child.material.emissiveMap = child.material.map;
+            //                     // child.material.envMap = child.material.map;
+            //                     // child.material.alphaMap = child.material.map;
+            //                     // child.material.aoMap = child.material.map;
+            //                     // child.material.bumpMap = child.material.map;
+            //                     // child.material.lightMap = child.material.map;
+            //                     // child.material.normalMap = child.material.map;
+            //                     // child.material.specularMap = child.material.map;
+            //                     // child.material.transparent = true;
+            //                     child.castShadow = true;
+            //                     child.receiveShadow = true;
+            //                 }
+            //             });
+            //         }
+            //         _ChangeMaterialEmissive(obj);
+            //         // obj.traverse(function (child) {
+            //         //     if (child.isMesh) {
+            //         //         // child.material.emissive = new THREE.Color(1, 1, 1);
+            //         //         child.material.emissive = child.material.color;
+            //         //         child.material.emissiveIntensity = 1;
+            //         //         child.material.emissiveMap = child.material.map;
+            //         //         child.castShadow = true;
+            //         //         child.receiveShadow = true;
+            //         //     }
+            //         // });
+            //         /*  for (let i = 0; i < obj.children.length; i++) {
+            //         // obj.children[i].position.set(0, -135, 0);
+            //         // obj.children[i].position.set(18, 36, 0);
+            //         // obj.children[i].scale.set(30, 30, 30);
+            //         // obj.children[i].scale.set(0.45, 0.45, 0.45);
+            //         obj.children[i].rotation.set(
+            //             (-90 * Math.PI) / 180,
+            //             0,
+            //             (-180 * Math.PI) / 180
+            //         );
+            //         // obj.children[i].transparent.set(0.5);
+            //         // that.transformControls.attach(obj.children[i]);
+            //     } */
+            //         obj.rotation.set(
+            //             (-90 * Math.PI) / 180,
+            //             0,
+            //             (-180 * Math.PI) / 180
+            //         );
+            //         // obj.scale.set(30, 30, 30);
+            //         // 查看动画数据  2个剪辑对象AnimationClip,一个有关键帧动画,一个没有
+            //         // console.log(obj.animations);
+            //         that.scene.add(obj);
+            //         // that.scene.add(obj.scene);
+            //     }
+            // );
+        },
+        initCar2() {
+            var that = this;
+            var loader2 = new THREE.ObjectLoader();
+            // var loader2 = new THREE.MeshLambertMaterial();
+            // loader2.load(`${that.publicPath}4.js`, function (obj) {
+            loader2.load(`${that.publicPath}car.json`, function (obj) {
+                // loader2.load(`${that.publicPath}Lidar.json`, function (obj) {
+                // console.log(obj);
+                obj.name = "car";
+                // console.log(obj.type);
+                // obj.position.set(0, 0, 0);
+                obj.scale.set(30, 30, 30);
+                obj.rotation.set(
+                    (-90 * Math.PI) / 180,
+                    0,
+                    (-90 * Math.PI) / 180
+                );
+                // obj.layers.set(1);
+                // that.transformControls.attach(obj);
+                that.scene.add(obj);
+            });
+        },
+        initCar3() {
+            var Loader = new MTLLoader(); //材质文件加载器
+            var loader = new OBJLoader(); //obj加载器
+            var that = this;
+
+            Loader.load(
+                // "../../../assets/common/image/female02/female02.mtl",
+                // "../../../../public/female02/female02.mtl",
+                // `${that.publicPath}male02/male02.mtl`,
+                // `${that.publicPath}GTR.mtl`,
+                // `${that.publicPath}lidar.mtl`,
+                // `${that.publicPath}female02/female02.mtl`,
+                // `${that.publicPath}new/audiq5.mtl`,
+                // `${that.publicPath}lb/obj/audiq5.mtl`,
+                // `${that.publicPath}lb/00obj/00.mtl`,
+                `${that.publicPath}lb/1/obj/untitled.mtl`,
+                function (materials) {
+                    // 返回一个包含材质的对象MaterialCreator
+                    // console.log(materials);
+                    // materials.transparent = true;
+                    // materials.opacity = 0.15;
+                    // materials.side = THREE.DoubleSide;
+                    // materials.depthWrite = false;
+                    //obj的模型会和MaterialCreator包含的材质对应起来
+                    loader.setMaterials(materials);
+                    loader.load(
+                        // "../../../../public/female02/female02.obj",
+                        // `${that.publicPath}female02/female02.obj`,
+                        // `${that.publicPath}new/audiq5.obj`,
+                        // `${that.publicPath}lb/00obj/00.obj`,
+                        `${that.publicPath}lb/1/obj/untitled.obj`,
+                        // `${that.publicPath}male02/male02.obj`,
+                        // `${that.publicPath}GTR.obj`,
+                        // `${that.publicPath}lidar.obj`,
+                        // `${that.publicPath}oddysey_2021.obj`,
+                        function (obj) {
+                            // console.log(obj);
+                            obj.name = "car";
+                            // console.log(obj.toJSON());
+                            // console.log(JSON.stringify(obj.toJSON()));
+                            // if (that.car) {
+                            //     that.scene.remove(that.car);
+                            // }
+
+                            for (let i = 0; i < obj.children.length; i++) {
+                                // obj.children[i].position.set(0, -135, 0);
+                                // obj.children[i].position.set(0, -30, 0);
+                                obj.children[i].position.set(0, 0, 0);
+                                // obj.children[i].scale.set(30, 30, 30);
+                                obj.children[i].rotation.set(
+                                    (-90 * Math.PI) / 180,
+                                    0,
+                                    (-180 * Math.PI) / 180
+                                );
+                                // obj.children[i].transparent.set(0.5);
+                                // that.transformControls.attach(obj.children[i]);
+                            }
+                            // that.transformControls.attach(that.cube);
+                            // console.log(obj.children[0].transparent);
+
+                            // that.transformControls.attach(obj);
+                            // that.car = obj;
+                            that.scene.add(obj); //返回的组对象插入场景中
+                            // this.camera.lookAt(obj);
+
+                            // loading.close();
+                            // that.camera.lookAt(obj.position);
+                            // 加载后操作
+                            // obj.children[0].scale.set(200, 200, 200); //缩放球体网格模型
+                            // 通过调节参数,地球表面的凹凸感更强
+                            // obj.children[0].material.normalScale.set(3, 3);
+                            // obj.children[0].position.set(100, 0, 0);
+                        }
+                    );
+                }
+            );
+        },
+        // 初始化车模型
+        initCar(model) {
+            // const loading = this.$loading({
+            //     lock: true,
+            //     text: "模型加载中,请稍等...",
+            //     // spinner: "el-icon-loading",
+            //     background: "rgba(0, 0, 0, 0.2)",
+            // });
+
+            // const car = this.scene.getObjectByName("car");
+            // console.log(car);
+            // console.log(this.scene);
+            // if (car) {
+            //     this.scene.remove(car);
+            // }
+
+            // console.log(type);
+
+            // if (type === "2") {
+            //     this.initCar1();
+            // } else if (type === "f") {
+            //     this.initCar2();
+            // } else if (type === "7") {
+            //     this.initCar3();
+            // } else {
+            //     this.initCar1();
+            // }
+
+            // console.log(model);
+            if (!model) return;
+            if (!model.includes(".glb")) return;
+
+            this.initCar0(model);
+
+            // console.log(this.scene);
+
+            // var Loader = new MTLLoader(); //材质文件加载器
+            // var loader = new OBJLoader(); //obj加载器
+            // var that = this;
+
+            /* var loader1 = new THREE.BufferGeometryLoader();
+            loader1.load(`${that.publicPath}car.json`, function (geometry) {
+            // loader1.load(`${that.publicPath}Lidar.json`, function (geometry) {
+                // 控制台查看加载放回的threejs对象结构
+                console.log(geometry);
+                var material = new THREE.MeshLambertMaterial({
+                    color: 0x0000ff,
+                }); //材质对象Material
+                var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
+                that.scene.add(mesh); //网格模型添加到场景中
+            }); */
+
+            // 没有材质文件,系统自动设置Phong网格材质
+            // loader.load("../../../assets/common/image/oddysey_2021.obj", function (obj) {
+            // loader.load("../../../assets/common/image/tree.obj", function (obj) {
+            // loader.load(`${that.publicPath}oddysey_2021.obj`, function (obj) {
+            // loader.load(`${that.publicPath}GTR.obj`, function (obj) {
+            /* loader.load(`${that.publicPath}Lidar.obj`, function (obj) {
+                if (that.car) {
+                    that.scene.remove(that.car);
+                }
+                console.log(666);
+                // console.log(JSON.stringify(obj.toJSON()));
+                that.car = obj;
+                // 控制台查看返回结构:包含一个网格模型Mesh的组Group
+                console.log(obj);
+                // loading.close();
+                // 查看加载器生成的材质对象:MeshPhongMaterial
+                // console.log(obj.children[0].material);
+                that.scene.add(obj);
+                for (let i = 0; i < obj.children.length; i++) {
+                    obj.children[i].position.set(0, 100, 0);
+                    obj.children[i].scale.set(20, 20, 20);
+                    // obj.children[i].layers.set(1);
+                }
+            }); */
+        },
+        // 初始化
+        init() {
+            this.initScene();
+            this.initCamera();
+            this.initRenderer();
+            this.initTransform();
+            this.initLight();
+            // this.initDragControls();
+
+            this.controls = new OrbitControls(
+                this.camera,
+                this.renderer.domElement
+            ); //创建控件对象
+            // this.controls.minDistance = 10;
+            // this.controls.maxDistance = 450;
+            this.controls.update();
+            // this.controls.target = this.cube.position
+        },
+        animate() {
+            this.raf = requestAnimationFrame(this.animate);
+            this.renderer.render(this.scene, this.camera);
+            if (this.transformControls) {
+                this.transformControls.update();
+            }
+
+            this.controls.update();
+
+            // this.renderer.setClearColor("#272727");
+
+            // this.renderer.setViewport(
+            //     0,
+            //     0,
+            //     this.container.clientWidth,
+            //     this.container.clientHeight
+            // );
+
+            // this.renderer.render(this.scene, this.camera);
+            
+            return;
+
+            // this.renderer.setClearColor(0xff00ff, 1);
+
+            // inset scene
+
+            this.renderer.setClearColor(0xdddddd, 1);
+
+            this.renderer.clearDepth(); // important!
+
+            this.renderer.setScissorTest(true);
+
+            let insetWidth = this.container.clientWidth / 4; // square
+            let insetHeight = this.container.clientHeight / 4;
+
+            this.renderer.setScissor(20, 20, insetWidth, insetHeight);
+
+            this.renderer.setViewport(20, 20, insetWidth, insetHeight);
+
+            this.camera2.position.copy(this.camera.position);
+            this.camera2.quaternion.copy(this.camera.quaternion);
+
+            this.scene2 = new THREE.Scene();
+
+            var cubeGeometry = new THREE.ConeGeometry(75, 150, 6, 1, false);
+            cubeGeometry.translate(0, -75, 0);
+
+            let obj = {
+                color: 0x4c4c4c,
+                // wireframe: true,
+                // transparent: true,
+                // opacity: 0.3,
+                // ambient: 0x00ff00,
+                // emissive: 0x00ff00,
+                lightMapIntensity: 0.1,
+            };
+
+            var cubeMaterial = new THREE.MeshLambertMaterial(obj);
+            let cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
+            this.scene2.add(cube);
+
+            this.renderer.render(this.scene2, this.camera2);
+
+            this.renderer.setScissorTest(false);
+        },
+        onWindowResize() {
+            this.camera.aspect =
+                this.container.clientWidth / this.container.clientHeight;
+            this.camera.updateProjectionMatrix();
+
+            this.renderer.setSize(
+                this.container.clientWidth,
+                this.container.clientHeight
+            );
+
+            let insetWidth = this.container.clientWidth / 4; // square
+            let insetHeight = this.container.clientHeight / 4;
+
+            // this.camera2.aspect = insetWidth / insetHeight;
+            // this.camera2.updateProjectionMatrix();
+        },
+        go() {
+            this.container = document.getElementById("container");
+            this.init();
+            this.animate();
+
+            window.addEventListener("resize", this.onWindowResize);
+        },
+        // 每编辑一个传感器则重新生成对应的物体
+        reset(type) {
+            this.canDrag = true;
+
+            if (this.cacheList.length > 0) {
+                this.scene.remove(...this.cacheList);
+                this.cacheList.forEach((i) => {
+                    this.clearCache(i);
+                });
+                this.cacheList = [];
+            }
+
+            this.sensor = null;
+
+            const obj1 = this.scene.getObjectByName("cube");
+            if (obj1) {
+                this.scene.remove(obj1);
+            }
+
+            this.xAngle = 0;
+            this.yAngle = 0;
+            this.zAngle = 0;
+
+            let z = +this.$parent.formA.sensorX || 0;
+            let x = +this.$parent.formA.sensorY || 0;
+            let y = +this.$parent.formA.sensorZ || 0;
+            let h = +this.$parent.formA.sensorP || 0;
+            let p = +this.$parent.formA.sensorR || 0;
+            let r = +this.$parent.formA.sensorH || 0;
+
+            x = Math.floor(x / this.rate);
+            y = Math.floor(y / this.rate);
+            z = Math.floor(z / this.rate);
+
+            this.initContent(
+                null,
+                { x, y, z },
+                {
+                    x: (-90 * Math.PI) / 180,
+                    y: 0,
+                    z: 0,
+                },
+                type
+            );
+
+            setTimeout(() => {
+                this.initSensor({ x, y, z }, type, true);
+
+                const obj = this.scene.getObjectByName("cube");
+
+                obj.position.x = x;
+                obj.position.y = y;
+                obj.position.z = z;
+
+                // obj.rotateX(0 * -1);
+                // obj.rotateX((h * Math.PI) / 180);
+                this.xAngle = ((h - 90) * Math.PI) / 180;
+
+                // obj.rotateY(0 * -1);
+                // obj.rotateY((p * Math.PI) / 180);
+                this.yAngle = (p * Math.PI) / 180;
+
+                // obj.rotateZ(0 * -1);
+                // obj.rotateZ((r * Math.PI) / 180);
+                this.zAngle = (r * Math.PI) / 180;
+                obj.rotation.set(this.xAngle, this.yAngle, this.zAngle);
+            }, 0);
+        },
+        // 初始化传感器
+        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 === "ogt1") {
+                var loader2 = new THREE.ObjectLoader();
+                loader2.load(
+                    `${that.publicPath}sensor/ogt/ogt.json`,
+                    function (obj) {
+                        // console.log(obj);
+                        that.cacheList.push(obj);
+                        for (let i = 0; i < obj.children.length; i++) {
+                            obj.children[i].scale.set(0.2, 0.2, 0.2);
+                        }
+                        obj.position.set(pos.x, pos.y, pos.z);
+                        obj.name = "ogt";
+                        if (canMove) {
+                            that.sensor = obj;
+                        }
+                        that.scene.add(obj);
+                    }
+                );
+                return;
+            }
+
+            if (type === "ogt1" && this.ogt) {
+                setTimeout(() => {
+                    let obj1 = this.ogt;
+                    // for (let i = 0; i < obj1.children.length; i++) {
+                    //     obj1.children[i].scale.set(0.2, 0.2, 0.2);
+                    // }
+                    obj1.position.set(pos.x, pos.y, pos.z);
+
+                    if (canMove) {
+                        that.sensor = obj1;
+                    }
+                    obj1.name = "ogt";
+                    // console.log(that.scene);
+
+                    that.scene.add(obj1); //返回的组对象插入场景中
+                }, 600);
+                return;
+            }
+
+            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`;
+            }
+
+            let loading = null;
+            if (type === "ogt") {
+                // loading = this.$loading({
+                //     lock: true,
+                //     text: "模型加载中,请稍等...",
+                //     // spinner: "el-icon-loading",
+                //     background: "rgba(0, 0, 0, 0.2)",
+                // });
+                showFullScreenLoading();
+            }
+
+            Loader.load(
+                mtlUrl,
+                function (materials) {
+                    // console.log(materials);
+                    loader.setMaterials(materials);
+                    loader.load(objUrl, function (obj) {
+                        // console.log(obj);
+                        // console.log(obj.clone());
+                        // console.log(JSON.stringify(obj.toJSON()));
+                        // if (type === "ogt" && !that.ogt) {
+                        //     that.ogt = obj.clone();
+                        // }
+
+                        if (type === "ogt") {
+                            // loading.close();
+                            tryHideFullScreenLoading();
+                        }
+
+                        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(0.8, 0.8, 0.8);
+                            } else if (type === "ogt") {
+                                obj.children[i].scale.set(0.2, 0.2, 0.2);
+                            } else if (type === "lidar") {
+                                obj.children[i].scale.set(0.1, 0.1, 0.1);
+                            } else if (type === "gps") {
+                                obj.children[i].scale.set(40, 40, 40);
+                            }
+                            // obj.children[i].position.set(0, 0, 0);
+                            // obj.children[i].geometry.translate(pos.x, pos.y, pos.z);
+                            // obj.children[i].position.set(pos.x, pos.y, pos.z);
+                            // obj.children[i].geometry.translate(-pos.x, -pos.y, -pos.z);
+                            // obj.children[i].scale.set(30, 30, 30);
+                        }
+                        obj.position.set(pos.x, pos.y, pos.z);
+                        // obj.geometry.translate.set(pos.x, pos.y, pos.z);
+
+                        if (canMove) {
+                            that.sensor = obj;
+                        }
+
+                        that.scene.add(obj); //返回的组对象插入场景中
+                    });
+                },
+                (xhr) => {
+                    // console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
+                },
+                (error) => {
+                    if (type === "ogt") {
+                        // loading.close();
+                        tryHideFullScreenLoading();
+                    }
+                    console.error(error);
+                }
+            );
+        },
+        // 初始化已保存过的传感器
+        initContentToShow(r, position, rotation, type) {
+            var cubeGeometry = new THREE.ConeGeometry(
+                r || 45 * this.scale,
+                150 * this.scale,
+                4,
+                1,
+                false
+            );
+            cubeGeometry.translate(0, -75 * this.scale, 0);
+
+            let obj = {
+                transparent: true,
+                opacity: 0.3,
+                // emissive: 0xfaff72,
+                lightMapIntensity: 0.1,
+                color: 0x4c4c4c,
+            };
+
+            if (type === "camera") {
+                obj.emissive = 0x000080;
+                // obj.color = 0xfaff72;
+            } else if (type === "ogt") {
+                obj.emissive = 0x008000;
+                // obj.color = 0x33cc66;
+            } else if (type === "lidar") {
+                // obj.emissive = 0xff0000;
+                // obj.color = 0xcc3366;
+                obj.emissive = 0xff4500;
+            } else if (type === "gps") {
+                // obj.emissive = 0xfaff72;
+                // obj.color = 0x3366cc;
+                obj.emissive = 0x8a2be2;
+            }
+
+            var cubeMaterial = new THREE.MeshLambertMaterial(obj);
+            // var cubeMaterial = new THREE.MeshBasicMaterial(obj);
+
+            var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
+            cube.name = this.geometryName || "cubeA";
+            cube.rotateX((-90 * Math.PI) / 180);
+
+            if (position) {
+                cube.position.x = position.x;
+                cube.position.y = position.y;
+                cube.position.z = position.z;
+            }
+            if (rotation) {
+                // cube.rotateX(0 * -1);
+                // cube.rotateX((rotation.x * Math.PI) / 180);
+                // cube.rotateY(0 * -1);
+                // cube.rotateY((rotation.y * Math.PI) / 180);
+                // cube.rotateZ(0 * -1);
+                // cube.rotateZ((rotation.z * Math.PI) / 180);
+
+                cube.rotation.set(
+                    ((rotation.x - 90) * Math.PI) / 180,
+                    (rotation.y * Math.PI) / 180,
+                    (rotation.z * Math.PI) / 180
+                );
+            }
+            this.cacheList.push(cube);
+            this.scene.add(cube);
+        },
+        // 生成一种类型的全部显示器
+        showSensor(sensor, type) {
+            if (sensor && Array.isArray(sensor) && sensor.length > 0) {
+                sensor.forEach((item) => {
+                    this.initContentToShow(
+                        null,
+                        {
+                            z: Math.floor(item.sensorX / this.rate || 0),
+                            x: Math.floor(item.sensorY / this.rate || 0),
+                            y: Math.floor(item.sensorZ / this.rate || 0),
+                        },
+                        {
+                            x: +item.sensorP,
+                            y: +item.sensorR,
+                            z: +item.sensorH,
+                        },
+                        type
+                    );
+
+                    this.initSensor(
+                        {
+                            z: Math.floor(item.sensorX / this.rate || 0),
+                            x: Math.floor(item.sensorY / this.rate || 0),
+                            y: Math.floor(item.sensorZ / this.rate || 0),
+                        },
+                        type,
+                        false
+                    );
+                });
+            }
+        },
+        // 显示全部
+        showAll() {
+            // 避免重复加载所有传感器
+            if (!this.canDrag) return;
+
+            this.canDrag = false;
+            if (this.cacheList.length > 0) {
+                this.scene.remove(...this.cacheList);
+                this.cacheList = [];
+            }
+
+            const obj = this.scene.getObjectByName("cube");
+            if (obj) {
+                this.scene.remove(obj);
+            }
+
+            if (this.dragControls) {
+                this.dragControls.deactivate();
+                this.dragControls.dispose();
+                this.dragControls = null;
+            }
+
+            if (this.transformControls) {
+                this.transformControls.detach();
+            }
+
+            // console.log(this.configList);
+
+            this.showSensor(this.configList.camera, "camera");
+            this.showSensor(this.configList.ogt, "ogt");
+            this.showSensor(this.configList.lidar, "lidar");
+            this.showSensor(this.configList.gps, "gps");
+        },
+        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;
+        },
+        showTX() {
+            var pointsArr1 = [
+                // [5, -1, 33],
+                // [5, 11, 33],
+                // [-5, -1, 33],
+                // [-5, 11, 33],
+                [0, 0, 0],
+                [10, -11, 66],
+                [30, 31, 66],
+                [-20, -21, 66],
+                [-30, 21, 66],
+            ];
+
+            let x = 0,
+                y = 0,
+                z = 0;
+
+            let r = 60;
+            z = r;
+
+            let a = 120,
+                b = 40;
+
+            x = Math.tan(THREE.MathUtils.degToRad(a / 2)) * r;
+            y = Math.tan(THREE.MathUtils.degToRad(b / 2)) * r;
+
+            let x1 = 0,
+                y1 = 0,
+                z1 = 0;
+
+            let r1 = 20;
+            z1 = r1;
+
+            x1 = Math.tan(THREE.MathUtils.degToRad(a / 2)) * r1;
+            y1 = Math.tan(THREE.MathUtils.degToRad(b / 2)) * r1;
+
+            let pointsArr2 = [
+                [0, 0, 0],
+                // [-x1, y1, z1],
+                // [-x1, -y1, z1],
+                // [x1, y1, z1],
+                // [x1, -y1, z1],
+                [-x, y, z],
+                [-x, -y, z],
+                [x, y, z],
+                [x, -y, z],
+            ];
+
+            let x2 = 0,
+                y2 = 0,
+                z2 = 0,
+                x3 = 0,
+                y3 = 0,
+                z3 = 0,
+                x4 = 0,
+                y4 = 0,
+                z4 = 0,
+                x6 = 0,
+                y6 = 0,
+                z6 = 0,
+                r2 = 90,
+                a2 = 30,
+                b2 = 60,
+                c2 = 90,
+                d2 = 60;
+
+            x2 = Math.tan(THREE.MathUtils.degToRad(a2 / 2)) * r2;
+            y2 = Math.tan(THREE.MathUtils.degToRad(b2 / 2)) * r2;
+            x3 = Math.tan(THREE.MathUtils.degToRad(c2 / 2)) * r2;
+            y3 = Math.tan(THREE.MathUtils.degToRad(d2 / 2)) * r2;
+
+            let pointsArr3 = [
+                [0, 0, 0],
+                [-x2, y3, r2],
+                [-x3, -y3, r2],
+                [x2, y2, r2],
+                [x3, -y2, r2],
+            ];
+            // console.log(pointsArr3);
+
+            let points = pointsArr3.map(
+                (d) => new THREE.Vector3(d[0], d[1], d[2])
+            );
+
+            let material = new THREE.MeshPhongMaterial({
+                color: 0x2c85e1,
+                shininess: 60,
+                specular: 0x2c85e1,
+                // opacity: 0.5,
+                // transparent: true,
+            });
+
+            let tixing = new ConvexGeometry(points);
+            //通过ConvexGeometry凸包绘制一个梯台,当然也可以使用ExtrudeGeometry挤压几何体,
+            let tixingMesh = new THREE.Mesh(tixing, material);
+            this.scene.add(tixingMesh);
+            // console.log(tixingMesh);
+
+            /* let vertices = [];
+
+            vertices.push(-155, 24, 90);
+            vertices.push(-63, -24, 90);
+            vertices.push(155, 91, 90);
+            vertices.push(63, -90, 90);
+
+            const geometry1 = new THREE.BufferGeometry();
+            geometry1.setAttribute(
+                "position",
+                new THREE.Float32BufferAttribute(vertices, 3)
+            );
+
+            const material1 = new THREE.PointsMaterial({
+                color: 0xff0000,
+                size: 10,
+                fog: false,
+            });
+
+            const points1 = new THREE.Points(geometry1, material1);
+
+            this.scene.add(points1); */
+
+            // if (this.transformControls) {
+            //     this.transformControls.attach(tixingMesh);
+            // }
+
+            // const a = new THREE.Vector3(1, 1, 0);
+            // const b = new THREE.Vector3(0, 0, 0);
+            // const d = a.distanceTo(b);
+            // const e = a.angleTo(b);
+
+            // console.log(d, e, (e * 180) / Math.PI, THREE.MathUtils.radToDeg(e));
+
+            // (value * Math.PI) / 180;
+        },
+        a() {
+            let line, thresholdLine, segments, thresholdSegments;
+            let renderer, scene, scene2, camera, camera2, controls;
+            let raycaster, sphereInter, sphereOnLine;
+            let matLine, matThresholdLine;
+
+            // viewport
+            let insetWidth;
+            let insetHeight;
+
+            const pointer = new THREE.Vector2(Infinity, Infinity);
+
+            init();
+            animate();
+
+            function init() {
+                let container = document.getElementById("container");
+                renderer = new THREE.WebGLRenderer({
+                    antialias: true,
+                    alpha: true,
+                });
+                renderer.setPixelRatio(window.devicePixelRatio);
+                renderer.setClearColor(0x00ff00);
+                renderer.setSize(container.clientWidth, container.clientHeight);
+                container.appendChild(renderer.domElement);
+
+                scene = new THREE.Scene();
+
+                camera = new THREE.PerspectiveCamera(
+                    40,
+                    container.clientWidth / container.clientHeight,
+                    1,
+                    1000
+                );
+                camera.position.set(-40, 0, 60);
+
+                camera2 = new THREE.PerspectiveCamera(40, 1, 1, 1000);
+                camera2.position.copy(camera.position);
+
+                controls = new OrbitControls(camera, renderer.domElement);
+                controls.minDistance = 10;
+                controls.maxDistance = 500;
+
+                // raycaster = new THREE.Raycaster();
+                // raycaster.params.Line2 = {};
+                // raycaster.params.Line2.threshold = 0;
+
+                // const sphereGeometry = new THREE.SphereGeometry(0.25);
+                // const sphereInterMaterial = new THREE.MeshBasicMaterial({
+                //     color: 0xff0000,
+                //     depthTest: false,
+                // });
+                // const sphereOnLineMaterial = new THREE.MeshBasicMaterial({
+                //     color: 0x00ff00,
+                //     depthTest: false,
+                // });
+
+                // sphereInter = new THREE.Mesh(
+                //     sphereGeometry,
+                //     sphereInterMaterial
+                // );
+                // sphereOnLine = new THREE.Mesh(
+                //     sphereGeometry,
+                //     sphereOnLineMaterial
+                // );
+                // sphereInter.visible = false;
+                // sphereOnLine.visible = false;
+                // sphereInter.renderOrder = 10;
+                // sphereOnLine.renderOrder = 10;
+                // scene.add(sphereInter);
+                // scene.add(sphereOnLine);
+
+                // Position and THREE.Color Data
+
+                const positions = [];
+                const colors = [];
+                const points = [];
+                for (let i = -50; i < 50; i++) {
+                    const t = i / 3;
+                    points.push(
+                        new THREE.Vector3(
+                            t * Math.sin(2 * t),
+                            t,
+                            t * Math.cos(2 * t)
+                        )
+                    );
+                }
+
+                const spline = new THREE.CatmullRomCurve3(points);
+                const divisions = Math.round(3 * points.length);
+                const point = new THREE.Vector3();
+                const color = new THREE.Color();
+
+                for (let i = 0, l = divisions; i < l; i++) {
+                    const t = i / l;
+
+                    spline.getPoint(t, point);
+                    positions.push(point.x, point.y, point.z);
+
+                    color.setHSL(t, 1.0, 0.5);
+                    colors.push(color.r, color.g, color.b);
+                }
+
+                const lineGeometry = new LineGeometry();
+                lineGeometry.setPositions(positions);
+                lineGeometry.setColors(colors);
+
+                const segmentsGeometry = new LineSegmentsGeometry();
+                segmentsGeometry.setPositions(positions);
+                segmentsGeometry.setColors(colors);
+
+                matLine = new LineMaterial({
+                    color: 0xffffff,
+                    linewidth: 1, // in world units with size attenuation, pixels otherwise
+                    worldUnits: true,
+                    vertexColors: true,
+
+                    //resolution:  // to be set by renderer, eventually
+                    alphaToCoverage: true,
+                });
+
+                matThresholdLine = new LineMaterial({
+                    color: 0xffffff,
+                    linewidth: matLine.linewidth, // in world units with size attenuation, pixels otherwise
+                    worldUnits: true,
+                    // vertexColors: true,
+                    transparent: true,
+                    opacity: 0.2,
+                    depthTest: false,
+                    visible: false,
+                    //resolution:  // to be set by renderer, eventually
+                });
+
+                // segments = new LineSegments2(segmentsGeometry, matLine);
+                // segments.computeLineDistances();
+                // segments.scale.set(1, 1, 1);
+                // scene.add(segments);
+                // segments.visible = false;
+
+                // thresholdSegments = new LineSegments2(
+                //     segmentsGeometry,
+                //     matThresholdLine
+                // );
+                // thresholdSegments.computeLineDistances();
+                // thresholdSegments.scale.set(1, 1, 1);
+                // scene.add(thresholdSegments);
+                // thresholdSegments.visible = false;
+
+                line = new Line2(lineGeometry, matLine);
+                line.computeLineDistances();
+                line.scale.set(1, 1, 1);
+                // scene.add(line);
+
+                var cubeGeometry = new THREE.ConeGeometry(75, 150, 4, 1, false);
+                cubeGeometry.translate(0, -75, 0);
+
+                let obj = {
+                    color: 0x4c4c4c,
+                    // wireframe: true,
+                    transparent: true,
+                    opacity: 0.3,
+                    // ambient: 0x00ff00,
+                    emissive: 0x0000ff,
+                    lightMapIntensity: 0.1,
+                };
+
+                var cubeMaterial = new THREE.MeshLambertMaterial(obj);
+                let cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
+                scene.add(cube);
+
+                // thresholdLine = new Line2(lineGeometry, matThresholdLine);
+                // thresholdLine.computeLineDistances();
+                // thresholdLine.scale.set(1, 1, 1);
+                // scene.add(thresholdLine);
+
+                const geo = new THREE.BufferGeometry();
+                geo.setAttribute(
+                    "position",
+                    new THREE.Float32BufferAttribute(positions, 3)
+                );
+                geo.setAttribute(
+                    "color",
+                    new THREE.Float32BufferAttribute(colors, 3)
+                );
+
+                //
+                document.addEventListener("pointermove", onPointerMove);
+                window.addEventListener("resize", onWindowResize);
+                onWindowResize();
+            }
+
+            function onWindowResize() {
+                camera.aspect = container.clientWidth / container.clientHeight;
+                camera.updateProjectionMatrix();
+
+                renderer.setSize(container.clientWidth, container.clientHeight);
+
+                insetWidth = container.clientHeight / 4; // square
+                insetHeight = container.clientHeight / 4;
+
+                camera2.aspect = insetWidth / insetHeight;
+                camera2.updateProjectionMatrix();
+            }
+
+            function onPointerMove(event) {
+                pointer.x = (event.clientX / container.clientWidth) * 2 - 1;
+                pointer.y = -(event.clientY / container.clientHeight) * 2 + 1;
+            }
+
+            function animate() {
+                requestAnimationFrame(animate);
+
+                // main scene
+
+                renderer.setClearColor(0xdddddd);
+
+                renderer.setViewport(
+                    0,
+                    0,
+                    container.clientWidth,
+                    container.clientHeight
+                );
+
+                // raycaster.setFromCamera(pointer, camera);
+
+                // const obj = line.visible ? line : segments;
+                // const intersects = raycaster.intersectObject(obj, true);
+
+                // if (intersects.length > 0) {
+                //     sphereInter.visible = true;
+                //     sphereOnLine.visible = true;
+                //     sphereInter.position.copy(intersects[0].point);
+                //     sphereOnLine.position.copy(intersects[0].pointOnLine);
+                //     const i = intersects[0].faceIndex;
+                //     const colors =
+                //         obj.geometry.getAttribute("instanceColorStart");
+                //     const color = new THREE.Color().setRGB(
+                //         colors.getX(i),
+                //         colors.getY(i),
+                //         colors.getZ(i)
+                //     );
+                //     sphereInter.material.color.copy(
+                //         color.clone().offsetHSL(0.3, 0, 0)
+                //     );
+                //     sphereOnLine.material.color.copy(
+                //         color.clone().offsetHSL(0.7, 0, 0)
+                //     );
+                //     renderer.domElement.style.cursor = "crosshair";
+                // } else {
+                //     sphereInter.visible = false;
+                //     sphereOnLine.visible = false;
+                //     renderer.domElement.style.cursor = "";
+                // }
+
+                // renderer will set this eventually
+                matLine.resolution.set(
+                    container.clientWidth,
+                    container.clientHeight
+                ); // resolution of the viewport
+                matThresholdLine.resolution.set(
+                    container.clientWidth,
+                    container.clientHeight
+                ); // resolution of the viewport
+
+                // gpuPanel.startQuery();
+                renderer.render(scene, camera);
+                // gpuPanel.endQuery();
+
+                // inset scene
+
+                renderer.setClearColor(0xff00ff, 1);
+
+                renderer.clearDepth(); // important!
+
+                renderer.setScissorTest(true);
+
+                renderer.setScissor(20, 20, insetWidth, insetHeight);
+
+                renderer.setViewport(20, 20, insetWidth, insetHeight);
+
+                camera2.position.copy(camera.position);
+                camera2.quaternion.copy(camera.quaternion);
+
+                // renderer will set this eventually
+                matLine.resolution.set(insetWidth, insetHeight); // resolution of the inset viewport
+
+                scene2 = new THREE.Scene();
+
+                var cubeGeometry = new THREE.ConeGeometry(75, 150, 6, 1, false);
+                cubeGeometry.translate(0, -75, 0);
+
+                let obj = {
+                    color: 0x4c4c4c,
+                    // wireframe: true,
+                    // transparent: true,
+                    // opacity: 0.3,
+                    // ambient: 0x00ff00,
+                    // emissive: 0x00ff00,
+                    lightMapIntensity: 0.1,
+                };
+
+                var cubeMaterial = new THREE.MeshLambertMaterial(obj);
+                let cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
+                scene2.add(cube);
+
+                renderer.render(scene2, camera2);
+
+                renderer.setScissorTest(false);
+            }
+        },
+    },
+
+    mounted() {
+        // this.a();
+        this.go();
+        // this.showTX();
+
+        // console.log(THREE.Loader.Handlers.add);
+        // THREE.Loader.Handlers.add( /\.dds$/i, new DDSLoader() );
+
+        // console.log(new THREE.LoadingManager()); RGBELoader
+        // let dds = new THREE.LoadingManager();
+        // dds.addHandler(/\.dds$/i, new DDSLoader());
+        // dds.addHandler(/\.rgb$/i, new RGBELoader());
+        // console.log(dds);
+
+        // THREE.DefaultLoadingManager.addHandler(/\.dds$/i, new DDSLoader());
+        // THREE.DefaultLoadingManager.addHandler(/\.rgb$/i, new RGBELoader());
+        // console.log(THREE.DefaultLoadingManager);
+
+        // console.log(THREE.LoadingManager.addHandler);
+        // THREE.Loader.Handlers.add( /\.dds$/i, new DDSLoader());
+        // THREE.Loader.addHandler(/\.dds$/i, new DDSLoader());
+        // THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
+        // THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
+
+        // if (!this.isAdd) {
+        //     setTimeout(() => {
+        //         this.initCar();
+        //     }, 270);
+        // }
+    },
+    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.scene2 = null;
+
+        this.camera = null;
+        this.camera2 = 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;
+
+        THREE.Cache.clear();
+    },
+};
+</script>
+
+<style lang="less" scoped>
+#container {
+    width: 100%;
+    height: calc(100vh - 125px);
+}
+</style>

+ 418 - 5
src/views/modelLibrary/components/threeVehicleConfiguration.vue

@@ -15,11 +15,17 @@ import { MTLLoader } from "three/examples/jsm/loaders/MTLLoader.js";
 // import { DDSLoader } from "three/examples/jsm/loaders/DDSLoader.js";
 // import { DDSLoader } from "three/examples/jsm/loaders/DDSLoader.js";
 import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
 import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
 import { ConvexGeometry } from "three/examples/jsm/geometries/ConvexGeometry.js";
 import { ConvexGeometry } from "three/examples/jsm/geometries/ConvexGeometry.js";
+// import { LineGeometry } from "three/examples/jsm/lines/LineGeometry.js";
+// import { LineSegmentsGeometry } from "three/examples/jsm/lines/LineSegmentsGeometry.js";
+// import { LineMaterial } from "three/examples/jsm/lines/LineMaterial.js";
+// import { LineSegments2 } from "three/examples/jsm/lines/LineSegments2.js";
+// import { Line2 } from "three/examples/jsm/lines/Line2.js";
 import {
 import {
     showFullScreenLoading,
     showFullScreenLoading,
     tryHideFullScreenLoading,
     tryHideFullScreenLoading,
 } from "../../../axios/filter";
 } from "../../../axios/filter";
 import { mapState } from "vuex";
 import { mapState } from "vuex";
+import CoordinateAxes from "../common/coordinateAxes";
 
 
 export default {
 export default {
     name: "threeVehicleConfiguration", // 车辆配置详情中的threeJS
     name: "threeVehicleConfiguration", // 车辆配置详情中的threeJS
@@ -29,7 +35,9 @@ export default {
         return {
         return {
             publicPath: process.env.BASE_URL,
             publicPath: process.env.BASE_URL,
             scene: null,
             scene: null,
+            scene2: null,
             camera: null,
             camera: null,
+            camera2: null,
             renderer: null,
             renderer: null,
             light: null,
             light: null,
             transformControls: null,
             transformControls: null,
@@ -182,11 +190,34 @@ export default {
             this.scene = new THREE.Scene();
             this.scene = new THREE.Scene();
             let axes = new THREE.AxesHelper(1500);
             let axes = new THREE.AxesHelper(1500);
             this.scene.add(axes);
             this.scene.add(axes);
+
             const gridHelper = new THREE.GridHelper(1000, 100);
             const gridHelper = new THREE.GridHelper(1000, 100);
             gridHelper.material.opacity = 0.25;
             gridHelper.material.opacity = 0.25;
             gridHelper.material.transparent = true;
             gridHelper.material.transparent = true;
             this.scene.add(gridHelper);
             this.scene.add(gridHelper);
 
 
+            /* var cubeGeometry = new THREE.ConeGeometry(75, 150, 6, 1, false);
+            cubeGeometry.translate(0, -75, 0);
+
+            let obj = {
+                color: 0x4c4c4c,
+                // wireframe: true,
+                // transparent: true,
+                // opacity: 0.3,
+                // ambient: 0x00ff00,
+                // emissive: 0x00ff00,
+                lightMapIntensity: 0.1,
+            };
+
+            var cubeMaterial = new THREE.MeshLambertMaterial(obj);
+            let cube = new THREE.Mesh(cubeGeometry, cubeMaterial); */
+
+            this.scene2 = new THREE.Scene();
+            let cube = new CoordinateAxes();
+            this.scene2.add(cube);
+
+            return;
+
             // const geometry = new THREE.BoxGeometry(100, 100, 100);
             // const geometry = new THREE.BoxGeometry(100, 100, 100);
             // const material = new THREE.MeshBasicMaterial({
             // const material = new THREE.MeshBasicMaterial({
             //     color: 0xffffff,
             //     color: 0xffffff,
@@ -241,13 +272,18 @@ export default {
                 0.1,
                 0.1,
                 1000
                 1000
             );
             );
-            // this.camera.layers.set(1);
 
 
             // this.camera = new THREE.PerspectiveCamera(45, 1.5, 1, 1000);
             // this.camera = new THREE.PerspectiveCamera(45, 1.5, 1, 1000);
             // this.camera.position.set(600, 600, 600);
             // this.camera.position.set(600, 600, 600);
             this.camera.position.set(200, 200, 200);
             this.camera.position.set(200, 200, 200);
             // this.camera.lookAt(this.scene.position);
             // this.camera.lookAt(this.scene.position);
-            this.scene.add(this.camera);
+            // this.scene.add(this.camera);
+            // this.scene.add(this.camera2);
+
+            this.camera2 = new THREE.PerspectiveCamera(75, 1, 0.1, 1000);
+            // this.camera2 = new THREE.PerspectiveCamera(40, 1, 1, 1000);
+            // this.camera2.position.copy(this.camera.position);
+            // this.camera.layers.set(1);
         },
         },
         // 渲染器
         // 渲染器
         initRenderer() {
         initRenderer() {
@@ -812,26 +848,68 @@ export default {
                 this.camera,
                 this.camera,
                 this.renderer.domElement
                 this.renderer.domElement
             ); //创建控件对象
             ); //创建控件对象
+            this.controls.minDistance = 10;
+            this.controls.maxDistance = 450;
             this.controls.update();
             this.controls.update();
             // this.controls.target = this.cube.position
             // this.controls.target = this.cube.position
         },
         },
         animate() {
         animate() {
             this.raf = requestAnimationFrame(this.animate);
             this.raf = requestAnimationFrame(this.animate);
-            this.renderer.render(this.scene, this.camera);
+            // this.renderer.render(this.scene, this.camera);
             if (this.transformControls) {
             if (this.transformControls) {
                 this.transformControls.update();
                 this.transformControls.update();
             }
             }
 
 
             this.controls.update();
             this.controls.update();
+
+            // this.renderer.setClearColor("#272727");
+
+            this.renderer.setViewport(
+                0,
+                0,
+                this.container.clientWidth,
+                this.container.clientHeight
+            );
+
+            this.renderer.render(this.scene, this.camera);
+
+            // inset scene
+
+            // this.renderer.setClearColor(0xdddddd, 1);
+
+            this.renderer.clearDepth(); // important!
+
+            this.renderer.setScissorTest(true);
+
+            let insetWidth = this.container.clientWidth / 4; // square
+            let insetHeight = this.container.clientHeight / 4;
+
+            this.renderer.setScissor(2, 350, insetWidth, insetHeight);
+
+            this.renderer.setViewport(2, 350, insetWidth, insetHeight);
+
+            this.camera2.position.copy(this.camera.position);
+            this.camera2.quaternion.copy(this.camera.quaternion);
+
+            this.renderer.render(this.scene2, this.camera2);
+
+            this.renderer.setScissorTest(false);
         },
         },
         onWindowResize() {
         onWindowResize() {
             this.camera.aspect =
             this.camera.aspect =
                 this.container.clientWidth / this.container.clientHeight;
                 this.container.clientWidth / this.container.clientHeight;
             this.camera.updateProjectionMatrix();
             this.camera.updateProjectionMatrix();
+
             this.renderer.setSize(
             this.renderer.setSize(
                 this.container.clientWidth,
                 this.container.clientWidth,
                 this.container.clientHeight
                 this.container.clientHeight
             );
             );
+
+            let insetWidth = this.container.clientWidth / 4; // square
+            let insetHeight = this.container.clientHeight / 4;
+
+            this.camera2.aspect = insetWidth / insetHeight;
+            this.camera2.updateProjectionMatrix();
         },
         },
         go() {
         go() {
             this.container = document.getElementById("container");
             this.container = document.getElementById("container");
@@ -841,7 +919,7 @@ export default {
             window.addEventListener("resize", this.onWindowResize);
             window.addEventListener("resize", this.onWindowResize);
         },
         },
         // 每编辑一个传感器则重新生成对应的物体
         // 每编辑一个传感器则重新生成对应的物体
-        reset(type) {
+        reset(type, onlyClear = false) {
             this.canDrag = true;
             this.canDrag = true;
 
 
             if (this.cacheList.length > 0) {
             if (this.cacheList.length > 0) {
@@ -863,6 +941,19 @@ export default {
             this.yAngle = 0;
             this.yAngle = 0;
             this.zAngle = 0;
             this.zAngle = 0;
 
 
+            if (this.dragControls) {
+                this.dragControls.deactivate();
+                this.dragControls.dispose();
+                this.dragControls = null;
+            }
+
+            if (this.transformControls) {
+                this.transformControls.detach();
+            }
+
+            // onlyClear若为true,表示只清除当前展示的东西,没有可增加展示的
+            if (onlyClear) return;
+
             let z = +this.$parent.formA.sensorX || 0;
             let z = +this.$parent.formA.sensorX || 0;
             let x = +this.$parent.formA.sensorY || 0;
             let x = +this.$parent.formA.sensorY || 0;
             let y = +this.$parent.formA.sensorZ || 0;
             let y = +this.$parent.formA.sensorZ || 0;
@@ -1044,7 +1135,7 @@ export default {
             );
             );
         },
         },
         // 初始化已保存过的传感器
         // 初始化已保存过的传感器
-        initContentToShow(r, position, rotation, type) {
+        initContentToShow(r, position = { x: 0, y: 0, z: 0 }, rotation, type) {
             var cubeGeometry = new THREE.ConeGeometry(
             var cubeGeometry = new THREE.ConeGeometry(
                 r || 45 * this.scale,
                 r || 45 * this.scale,
                 150 * this.scale,
                 150 * this.scale,
@@ -1111,6 +1202,15 @@ export default {
         showSensor(sensor, type) {
         showSensor(sensor, type) {
             if (sensor && Array.isArray(sensor) && sensor.length > 0) {
             if (sensor && Array.isArray(sensor) && sensor.length > 0) {
                 sensor.forEach((item) => {
                 sensor.forEach((item) => {
+                    // 若是传感器没保存配置项,则不展示
+                    if (
+                        item.sensorX == null &&
+                        item.sensorY == null &&
+                        item.sensorZ == null
+                    ) {
+                        return;
+                    }
+
                     this.initContentToShow(
                     this.initContentToShow(
                         null,
                         null,
                         {
                         {
@@ -1328,9 +1428,320 @@ export default {
 
 
             // (value * Math.PI) / 180;
             // (value * Math.PI) / 180;
         },
         },
+        a() {
+            let line, thresholdLine, segments, thresholdSegments;
+            let renderer, scene, scene2, camera, camera2, controls;
+            let raycaster, sphereInter, sphereOnLine;
+            let matLine, matThresholdLine;
+
+            // viewport
+            let insetWidth;
+            let insetHeight;
+
+            const pointer = new THREE.Vector2(Infinity, Infinity);
+
+            init();
+            animate();
+
+            function init() {
+                let container = document.getElementById("container");
+                renderer = new THREE.WebGLRenderer({
+                    antialias: true,
+                    alpha: true,
+                });
+                renderer.setPixelRatio(window.devicePixelRatio);
+                renderer.setClearColor(0x00ff00);
+                renderer.setSize(container.clientWidth, container.clientHeight);
+                container.appendChild(renderer.domElement);
+
+                scene = new THREE.Scene();
+
+                camera = new THREE.PerspectiveCamera(
+                    40,
+                    container.clientWidth / container.clientHeight,
+                    1,
+                    1000
+                );
+                camera.position.set(-40, 0, 60);
+
+                camera2 = new THREE.PerspectiveCamera(40, 1, 1, 1000);
+                camera2.position.copy(camera.position);
+
+                controls = new OrbitControls(camera, renderer.domElement);
+                controls.minDistance = 10;
+                controls.maxDistance = 500;
+
+                // raycaster = new THREE.Raycaster();
+                // raycaster.params.Line2 = {};
+                // raycaster.params.Line2.threshold = 0;
+
+                // const sphereGeometry = new THREE.SphereGeometry(0.25);
+                // const sphereInterMaterial = new THREE.MeshBasicMaterial({
+                //     color: 0xff0000,
+                //     depthTest: false,
+                // });
+                // const sphereOnLineMaterial = new THREE.MeshBasicMaterial({
+                //     color: 0x00ff00,
+                //     depthTest: false,
+                // });
+
+                // sphereInter = new THREE.Mesh(
+                //     sphereGeometry,
+                //     sphereInterMaterial
+                // );
+                // sphereOnLine = new THREE.Mesh(
+                //     sphereGeometry,
+                //     sphereOnLineMaterial
+                // );
+                // sphereInter.visible = false;
+                // sphereOnLine.visible = false;
+                // sphereInter.renderOrder = 10;
+                // sphereOnLine.renderOrder = 10;
+                // scene.add(sphereInter);
+                // scene.add(sphereOnLine);
+
+                // Position and THREE.Color Data
+
+                const positions = [];
+                const colors = [];
+                const points = [];
+                for (let i = -50; i < 50; i++) {
+                    const t = i / 3;
+                    points.push(
+                        new THREE.Vector3(
+                            t * Math.sin(2 * t),
+                            t,
+                            t * Math.cos(2 * t)
+                        )
+                    );
+                }
+
+                const spline = new THREE.CatmullRomCurve3(points);
+                const divisions = Math.round(3 * points.length);
+                const point = new THREE.Vector3();
+                const color = new THREE.Color();
+
+                for (let i = 0, l = divisions; i < l; i++) {
+                    const t = i / l;
+
+                    spline.getPoint(t, point);
+                    positions.push(point.x, point.y, point.z);
+
+                    color.setHSL(t, 1.0, 0.5);
+                    colors.push(color.r, color.g, color.b);
+                }
+
+                const lineGeometry = new LineGeometry();
+                lineGeometry.setPositions(positions);
+                lineGeometry.setColors(colors);
+
+                const segmentsGeometry = new LineSegmentsGeometry();
+                segmentsGeometry.setPositions(positions);
+                segmentsGeometry.setColors(colors);
+
+                matLine = new LineMaterial({
+                    color: 0xffffff,
+                    linewidth: 1, // in world units with size attenuation, pixels otherwise
+                    worldUnits: true,
+                    vertexColors: true,
+
+                    //resolution:  // to be set by renderer, eventually
+                    alphaToCoverage: true,
+                });
+
+                matThresholdLine = new LineMaterial({
+                    color: 0xffffff,
+                    linewidth: matLine.linewidth, // in world units with size attenuation, pixels otherwise
+                    worldUnits: true,
+                    // vertexColors: true,
+                    transparent: true,
+                    opacity: 0.2,
+                    depthTest: false,
+                    visible: false,
+                    //resolution:  // to be set by renderer, eventually
+                });
+
+                // segments = new LineSegments2(segmentsGeometry, matLine);
+                // segments.computeLineDistances();
+                // segments.scale.set(1, 1, 1);
+                // scene.add(segments);
+                // segments.visible = false;
+
+                // thresholdSegments = new LineSegments2(
+                //     segmentsGeometry,
+                //     matThresholdLine
+                // );
+                // thresholdSegments.computeLineDistances();
+                // thresholdSegments.scale.set(1, 1, 1);
+                // scene.add(thresholdSegments);
+                // thresholdSegments.visible = false;
+
+                line = new Line2(lineGeometry, matLine);
+                line.computeLineDistances();
+                line.scale.set(1, 1, 1);
+                // scene.add(line);
+
+                var cubeGeometry = new THREE.ConeGeometry(75, 150, 4, 1, false);
+                cubeGeometry.translate(0, -75, 0);
+
+                let obj = {
+                    color: 0x4c4c4c,
+                    // wireframe: true,
+                    transparent: true,
+                    opacity: 0.3,
+                    // ambient: 0x00ff00,
+                    emissive: 0x0000ff,
+                    lightMapIntensity: 0.1,
+                };
+
+                var cubeMaterial = new THREE.MeshLambertMaterial(obj);
+                let cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
+                scene.add(cube);
+
+                // thresholdLine = new Line2(lineGeometry, matThresholdLine);
+                // thresholdLine.computeLineDistances();
+                // thresholdLine.scale.set(1, 1, 1);
+                // scene.add(thresholdLine);
+
+                const geo = new THREE.BufferGeometry();
+                geo.setAttribute(
+                    "position",
+                    new THREE.Float32BufferAttribute(positions, 3)
+                );
+                geo.setAttribute(
+                    "color",
+                    new THREE.Float32BufferAttribute(colors, 3)
+                );
+
+                //
+                document.addEventListener("pointermove", onPointerMove);
+                window.addEventListener("resize", onWindowResize);
+                onWindowResize();
+            }
+
+            function onWindowResize() {
+                camera.aspect = container.clientWidth / container.clientHeight;
+                camera.updateProjectionMatrix();
+
+                renderer.setSize(container.clientWidth, container.clientHeight);
+
+                insetWidth = container.clientHeight / 4; // square
+                insetHeight = container.clientHeight / 4;
+
+                camera2.aspect = insetWidth / insetHeight;
+                camera2.updateProjectionMatrix();
+            }
+
+            function onPointerMove(event) {
+                pointer.x = (event.clientX / container.clientWidth) * 2 - 1;
+                pointer.y = -(event.clientY / container.clientHeight) * 2 + 1;
+            }
+
+            function animate() {
+                requestAnimationFrame(animate);
+
+                // main scene
+
+                renderer.setClearColor(0xdddddd);
+
+                renderer.setViewport(
+                    0,
+                    0,
+                    container.clientWidth,
+                    container.clientHeight
+                );
+
+                // raycaster.setFromCamera(pointer, camera);
+
+                // const obj = line.visible ? line : segments;
+                // const intersects = raycaster.intersectObject(obj, true);
+
+                // if (intersects.length > 0) {
+                //     sphereInter.visible = true;
+                //     sphereOnLine.visible = true;
+                //     sphereInter.position.copy(intersects[0].point);
+                //     sphereOnLine.position.copy(intersects[0].pointOnLine);
+                //     const i = intersects[0].faceIndex;
+                //     const colors =
+                //         obj.geometry.getAttribute("instanceColorStart");
+                //     const color = new THREE.Color().setRGB(
+                //         colors.getX(i),
+                //         colors.getY(i),
+                //         colors.getZ(i)
+                //     );
+                //     sphereInter.material.color.copy(
+                //         color.clone().offsetHSL(0.3, 0, 0)
+                //     );
+                //     sphereOnLine.material.color.copy(
+                //         color.clone().offsetHSL(0.7, 0, 0)
+                //     );
+                //     renderer.domElement.style.cursor = "crosshair";
+                // } else {
+                //     sphereInter.visible = false;
+                //     sphereOnLine.visible = false;
+                //     renderer.domElement.style.cursor = "";
+                // }
+
+                // renderer will set this eventually
+                matLine.resolution.set(
+                    container.clientWidth,
+                    container.clientHeight
+                ); // resolution of the viewport
+                matThresholdLine.resolution.set(
+                    container.clientWidth,
+                    container.clientHeight
+                ); // resolution of the viewport
+
+                // gpuPanel.startQuery();
+                renderer.render(scene, camera);
+                // gpuPanel.endQuery();
+
+                // inset scene
+
+                renderer.setClearColor(0xff00ff, 1);
+
+                renderer.clearDepth(); // important!
+
+                renderer.setScissorTest(true);
+
+                renderer.setScissor(20, 20, insetWidth, insetHeight);
+
+                renderer.setViewport(20, 20, insetWidth, insetHeight);
+
+                camera2.position.copy(camera.position);
+                camera2.quaternion.copy(camera.quaternion);
+
+                // renderer will set this eventually
+                matLine.resolution.set(insetWidth, insetHeight); // resolution of the inset viewport
+
+                scene2 = new THREE.Scene();
+
+                var cubeGeometry = new THREE.ConeGeometry(75, 150, 6, 1, false);
+                cubeGeometry.translate(0, -75, 0);
+
+                let obj = {
+                    color: 0x4c4c4c,
+                    // wireframe: true,
+                    // transparent: true,
+                    // opacity: 0.3,
+                    // ambient: 0x00ff00,
+                    // emissive: 0x00ff00,
+                    lightMapIntensity: 0.1,
+                };
+
+                var cubeMaterial = new THREE.MeshLambertMaterial(obj);
+                let cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
+                scene2.add(cube);
+
+                renderer.render(scene2, camera2);
+
+                renderer.setScissorTest(false);
+            }
+        },
     },
     },
 
 
     mounted() {
     mounted() {
+        // this.a();
         this.go();
         this.go();
         // this.showTX();
         // this.showTX();
 
 
@@ -1397,7 +1808,9 @@ export default {
         this.clearScene();
         this.clearScene();
 
 
         this.scene = null;
         this.scene = null;
+        this.scene2 = null;
         this.camera = null;
         this.camera = null;
+        this.camera2 = null;
         this.light = null;
         this.light = null;
         this.geometryName = null;
         this.geometryName = null;
         this.mesh = null;
         this.mesh = null;

+ 67 - 11
src/views/modelLibrary/vehicleConfigurationDetail.vue

@@ -142,15 +142,22 @@
             <div class="threeRight">
             <div class="threeRight">
                 <div class="viewBox">
                 <div class="viewBox">
                     <span
                     <span
-                        class="view el-icon-view"
-                        @click="showAll"
+                        v-show="!isOpen"
+                        class="view open"
+                        @click="showAll(true)"
                         title="显示全部"
                         title="显示全部"
                     ></span>
                     ></span>
+                    <span
+                        v-show="isOpen"
+                        class="view close"
+                        @click="showAll(false)"
+                        title="关闭全部"
+                    ></span>
                 </div>
                 </div>
 
 
-                <div class="axesHelperBox">
+                <!-- <div class="axesHelperBox">
                     <div class="axesHelperPic"></div>
                     <div class="axesHelperPic"></div>
-                </div>
+                </div> -->
 
 
                 <three-sensor
                 <three-sensor
                     ref="threeSensor"
                     ref="threeSensor"
@@ -471,6 +478,7 @@ export default {
             configBox: false, // 配置项box
             configBox: false, // 配置项box
             carModel: "", // 车模型
             carModel: "", // 车模型
             // rate: 20, // 坐标换算倍数
             // rate: 20, // 坐标换算倍数
+            isOpen: false, // 是否已展示全部传感器
         };
         };
     },
     },
 
 
@@ -660,11 +668,30 @@ export default {
             this.configBox = true;
             this.configBox = true;
         },
         },
         delOne(type, index) {
         delOne(type, index) {
+            if (this.curOne.name === type && this.curOne.index === index) {
+                this.curOne = {
+                    name: "",
+                    index: -1,
+                };
+
+                this.$refs.threeSensor.reset(null, true);
+                this.closeConfig();
+                
+                this.isOpen = false;
+            }
+
             this.configList[type].splice(index, 1);
             this.configList[type].splice(index, 1);
         },
         },
-        curItem(item, isAdd) {
+        curItem(item, isAdd, needDo = true) {
             this.$refs.formA.resetFields();
             this.$refs.formA.resetFields();
-            this.curOne = item;
+
+            this.isOpen = false;
+
+            // 若是两个参数是列表进来的需要赋值,函数直接调用的话不用
+            if (needDo) {
+                this.curOne = item;
+            }
+
             if (isAdd) {
             if (isAdd) {
                 this.formA.sensorX = "0";
                 this.formA.sensorX = "0";
                 this.formA.sensorY = "0";
                 this.formA.sensorY = "0";
@@ -778,9 +805,19 @@ export default {
             this.configBox = false;
             this.configBox = false;
         },
         },
         // 显示全部传感器
         // 显示全部传感器
-        showAll() {
-            this.$refs.threeSensor.showAll();
-            this.closeConfig();
+        showAll(needOpen) {
+            if (needOpen) {
+                this.$refs.threeSensor.showAll();
+                this.closeConfig();
+            } else {
+                if (this.curOne.index < 0) {
+                    this.$refs.threeSensor.reset(null, true);
+                } else {
+                    this.curItem(this.curOne, false, false);
+                }
+            }
+
+            this.isOpen = needOpen;
         },
         },
     },
     },
 
 
@@ -941,9 +978,28 @@ export default {
             opacity: 0.75;
             opacity: 0.75;
 
 
             .view {
             .view {
-                font-size: 18px;
+                display: block;
+                width: 30px;
+                height: 15px;
+                margin: 12px auto 0;
+                // font-size: 18px;
                 cursor: pointer;
                 cursor: pointer;
-                color: @themeColor;
+                // color: @themeColor;
+            }
+
+            .open {
+                background: url("../../assets/common/image/others/open.png")
+                    center no-repeat;
+                background-size: contain;
+            }
+
+            .close {
+                width: 26px;
+                height: 13px;
+                margin-top: 15px;
+                background: url("../../assets/common/image/others/close.png")
+                    center no-repeat;
+                background-size: contain;
             }
             }
         }
         }
 
 

Some files were not shown because too many files changed in this diff